根据C标准,很明显,常规函数调用是来自定义的表达式:
表达式是一个运算符和操作数的序列,它们指定值的计算,或者指定对象或函数,或者产生副作用,或者执行它们的组合。运算符的操作数的值计算在运算符结果的值计算之前进行排序。 (6.5.1)
由于()
是运算符,并且它返回一个值,因此常规函数调用显然是表达式。
但是那些不返回值的对象似乎不符合该定义。函数名称本身可以(因为它指定了一个函数),但这不是函数调用。
该标准确实明确指出函数调用是一个表达式,并且它可以返回void
,但这似乎与表达式的定义冲突。我想念什么?
答案 0 :(得分:4)
无论函数的返回类型如何,调用函数都是表达式。 C的语法与其类型系统正交。它们是语言的独立部分。在语法上func();
是一个表达式语句。
expression_statement
: ';'
| expression ';'
;
postfix_expression
: primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
对于void
结果,您可以做的事情很少。您不能将其分配给变量,因为不允许使用void
变量。如果func()
的结果为void
,则可以使用四个运算符:
(func())
func(), 42
42 ? func() : func()
。(void) func()
您还可以返回void
结果:
return func();
最后,在for(init; condition; increment)
循环中,这三个部分都是表达式。 init 和 increment (但不是 condition )可以是void
。
for (func(); 42; func()) { }
其中很少有用,没有一个是好的样式,但是它们都是合法的。
答案 1 :(得分:3)
关于void
的第6.5条第1款并未被完全考虑。 C标准不完善,存在许多缺陷。应当将本段作为一般说明,以方便读者阅读,而不是对表达式的精确数学说明。
答案 2 :(得分:1)
据说:
表达式是
的一系列运算符和操作数
- 指定值的计算,或
指定对象或函数的- 或
- 产生副作用
- 或执行其组合。
指定值的计算只是可能性中的一个。 void
函数调用将是“产生副作用”的函数。
C中的expression语句中的任何表达式均被视为void
表达式。 C11 6.8.3 Expression and null statements p2:
- 表达式语句中的表达式因其副作用而被评估为
void
表达式。 153)153) ,例如赋值和具有副作用的函数调用。
即在 statement
表达式中a = 5;
a = 5
是一个 void 表达式,仅对其副作用进行评估,即将值5
分配给a
,而不用于计算a即使a = 5
可以用于其他上下文中的值的计算。同样,您可以编写a;
,即使它没有表达式,也可以合法使用表达式“评估其副作用”。它并不会在那里停止表达。
逗号运算符的LHS是无效表达式。可以在? :
中使用void表达式-然后两个分支都将是void表达式,而整个表达式本身将是void表达式。
答案 3 :(得分:0)
C语言中的表达式可以为空。 这样的表达式没有值,因此无法将其分配给对象。 而且,任何表达式都可以转换为空。