来看一下下面的代码。
"Hello " "World!";
"The number is ", 37;
int x=23;
char *y="232";
x,x+2,x*3;
atoi(y) - x;
这是一个完全有效的C(99)源代码片段。 但是!所有这些表达式都没有返回值! 如何跟踪或使用所有这些匿名值? 它们存储在哪里,有什么目的?
来看一下下面的代码。
"Hello " "World!";
"The number is ", 37;
int x=23;
char *y="232";
x,x+2,x*3;
atoi(y) - x;
这是一个完全有效的C(99)源代码片段。 但是!所有这些表达式都没有返回值! 如何跟踪或使用所有这些匿名值? 它们存储在哪里,有什么目的?
这些值没有任何作用,您无法检索它们。实际上,大多数值被编译器优化掉了。
整个片段可以简化为 atoi("232") ,因为函数调用通常不能被优化掉。
atoi
在 C 标准中被定义为没有副作用的方式,因此一个好的编译器也会将其优化掉。(在程序中重新定义 atoi
(具有外部链接)的行为是未定义的,因此只要当前文件范围内没有静态定义,编译器就可以自由地假设它没有被重新定义。) - R.. GitHub STOP HELPING ICE那些特定的表达式是无用的。另一方面,这是被允许的,因为有些表达式具有副作用(也许有返回值),有时只需要副作用。
int main() {
1;
}
这段代码是否合法?如果是,那么它一直都是合法的。
return
语句,这段代码是否有效?我知道大多数编译器会勉强接受,但我认为在任何函数结尾都不返回(除了 C++ 中的 main
函数)是不严格有效的。 - Chris Lutz没有副作用的表达式并不特别有用。通常你会在这些地方找到一个函数调用,而函数体实际上会导致程序中的某些状态改变。
语言中有很多愚蠢的方法来什么都不做。考虑C语言语句:
;
它什么也不做。
printf(3)
时,如果没有检查其返回值,就会发生相同的情况,返回值将被丢弃。尽管函数调用可能具有副作用(printf(3)
肯定有副作用),因此仍会生成执行它的指令。大多数现代编译器将删除您列出的大多数语句,只要给定适当的优化标志即可。如果您真的想看到会发生什么,请使用(例如-O2
)和不使用优化的选项将您的源代码编译为汇编,并跟踪指令。y=0; x = ++y, y, ++y, y
在我的测试中将1分配给x(当然,在最后y为2)。 - ShinTakezoua, b
是简单的还是它应该总是(a, b)
...那么a, b
是什么,为什么a, b, c
和(a, b, c)
不同呢?幸运的是我从来没有使用过,
(也许只是在for
中“无意识”地使用了)!! - ShinTakezoua
的结果仍然在 b
中可用吗?
在哪里可以找到有关逗号运算符的更多信息? - Rizoa,b
中,首先计算a并丢弃(丢失)结果(如果有的话),然后计算b并取得结果。例如,x = a,b;
计算a,然后将b的评估结果分配给x。如果a对于b没有副作用,则可以编写x = b; a;
或a; x = b
。 - ShinTakezou