因为(a, b)
实际上是一个单一的价值.它计算a
并b
返回值b
.
那么你所做的基本上是:
/* calculate before `,` and ignore */ POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory"; /* call printf with after `,` */ printf(5);
这显然是错的.
当你写func(a, b)
一个函数调用时,C知道发送a
和b
作为单独的参数func
.当你说func((a, b))
,你明确地说(a, b)
是一个值,结果(即值b
)应func
作为一个参数发送.
如果您使用警告编译,并且您的编译器对您很好,它可能会警告您这一点.如果你的编译器是不是很好,但它仍然应该抱怨你是给了int
其中一个const char *
的预期.
如果使用gcc
,我强烈建议-Wall
总是编译.
因为(a, b)
实际上是一个单一的价值.它计算a
并b
返回值b
.
那么你所做的基本上是:
/* calculate before `,` and ignore */ POOLNAME_FMT "Cannot allocate %d bytes" POOLNAME_FMT "in pool not enough memory"; /* call printf with after `,` */ printf(5);
这显然是错的.
当你写func(a, b)
一个函数调用时,C知道发送a
和b
作为单独的参数func
.当你说func((a, b))
,你明确地说(a, b)
是一个值,结果(即值b
)应func
作为一个参数发送.
如果您使用警告编译,并且您的编译器对您很好,它可能会警告您这一点.如果你的编译器是不是很好,但它仍然应该抱怨你是给了int
其中一个const char *
的预期.
如果使用gcc
,我强烈建议-Wall
总是编译.
您正在使用逗号运算符而没有意识到:
( ... "in pool not enough memory",5) ^
因为逗号运算符将评估其左操作数并丢弃结果,然后计算并返回正确的操作数,最终得到:
printf( 5 ) ;
它将尝试将int
a 转换const char *restrict
为格式字符串,这几乎肯定不会指向有效的内存.如果没有()
,那,
将只是函数参数的分隔符.
这()
是在这种背景下的表达; 如果我们看一下C99草案标准部分的6.5.1
初级表达式,我们有:
( expression )
因此,
,我们可以从6.5.2
Postfix运算符部分看到它被视为运算符:
postfix-expression ( argument-expression-listopt )
argument-expression-list:
assignment-expression
argument-expression-list , assignment-expression
^
该,
只是在一个函数调用一个分隔符.
启用警告应该有帮助,gcc
给我一些警告:
警告:逗号表达式的左侧操作数无效[-Wunused-value]
和
警告:传递'printf'的参数1使得整数指针没有强制转换[默认情况下启用]注意:期望'const char*restrict'但参数类型为'int'