我最近看到一个帖子 What is the correct answer for cout << c++ << c;?并且想知道
的输出是否int c = 0;
printf ("%d %d", c++, c);
也未定义??
我在讲座中学习过后缀和前缀运算符仅在获得分号后才增加值。所以根据我的说法,输出 0 0
是正确的!!!
最佳答案
I have studied in lectures that post-fix and prefix operators increment value only after getting a semicolon.
让你的讲师来找我,这样我就可以拿棒球棒给他礼貌地指出他的错误。
具体什么时候应用前缀或后缀 ++
和 --
的副作用是未指定,除了要求它发生在下一个序列点之前。在像这样的表达式中
x = a++ * b
a
可能会在 a++
被评估后立即更新,或者更新可能被推迟到 a++ * b
被评估并且结果分配给 x
,或两者之间的任何地方。
这就是为什么像 i++ * i++
和 printf("%d %d", c++, c)
和 a[i++] = i
和许多其他人都是糟糕的 juju。根据编译器、优化设置、周围代码等,您将得到不同的结果。语言标准明确保留行为未定义,因此编译器没有义务“做正确的事”,无论如何正确的事情可能是。请记住,未定义行为 的定义是
3.4.3
1 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
3 EXAMPLE An example of undefined behavior is the behavior on integer overflow.
这是一个深思熟虑的设计决定 - 未指定这些操作的顺序的基本原理是让实现自由地重新排列评估顺序以进行优化。然而,为了换取这种自由,某些操作将不会有明确定义的结果。
请注意,编译器可以自由尝试检测这些情况并发出诊断; printf("%d %d", c++, c);
很容易捕捉到,但在一般情况下这将是一个检测错误。想象一下,如果写成 printf("%d %d", (*p)++, c)
;如果 p
指向 c
,则行为未定义,否则没问题。如果 p
被分配到不同的翻译单元,那么在编译时就没有办法知道这是否是一个问题。
这个概念并不难理解,但它是 C 语言中最常被误解(和误导)的方面之一。毫无疑问,这就是为什么 Java 和 C# 语言规范强制对所有内容执行特定的评估顺序(所有操作数都是从左到右评估的,并且所有副作用都会立即应用)。
关于c - 是 printf 的输出 ("%d %d", c++, c);也未定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10845122/