C标准中void函数调用作为表达式的定义冲突疑问
首先,咱们得回到C标准对表达式的完整定义,你可能只聚焦到了“指定值的计算”这部分,但实际上表达式的定义范围要宽得多:
An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.
看到没?四个条件满足任意一个就算表达式,不一定需要返回值。无返回值(void类型)的函数调用,核心就是靠“产生副作用”来符合这个定义——比如修改全局变量、执行I/O操作、调用其他有副作用的函数等等,这些都是这类表达式合法的存在意义。
接下来看标准对函数调用表达式的专门说明(针对void返回的情况):
If the expression that denotes the called function has type pointer to function returning void, the function call expression has type void; a void expression is evaluated for its side effects.
这里明确说了,返回void的函数调用表达式类型是void,这类表达式的存在目的就是为了执行它的副作用,而不是获取返回值。
你之前的困惑可能来自于误以为“表达式必须有可获取的值”,但C标准特意留出了void表达式的口子,就是为了处理这种只需要执行操作、不需要返回结果的场景。举个简单的例子:
void print_hello() { puts("Hello, C standard!"); } int main() { print_hello(); // 这个调用就是void类型的表达式,核心是执行输出的副作用 return 0; }
另外补充一点:()作为函数调用运算符,它的行为是根据被调用函数的返回类型来适配的。如果函数返回void,那么()运算符生成的表达式就是void类型,不需要产生可计算的值——这完全是标准允许的特殊情况,并没有和表达式的定义冲突。
内容的提问来源于stack exchange,提问作者teppic

