c-faq 和我的编译器之间的矛盾
C-faq 说代码:
int i = 7;
printf("%d\n", i++ * i++);
打印 49。无论如何评估的顺序,它不应该打印56吗? 当我在 Turbo C 3.0 编译器上运行这段代码时,它给出的输出是 56。为什么会出现矛盾呢?
The C-faq says that the code:
int i = 7;
printf("%d\n", i++ * i++);
prints 49. Regardless of the order of evaluation, shouldn't it print 56?
When I ran this code on my Turbo C 3.0 compiler it gave me the output of 56. Why is there a contradiction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这并不矛盾。这个问题是从用户角度出发的,如果你仔细阅读答案,你会发现这样的评论
所以它可能会打印 49 或 56。毕竟,未定义的行为是未定义的。这就是为什么不存在真正的矛盾。您可能想加深对所谓序列点的理解。
There is no contradiction. The question was worded from a user perspective, and if you carefully read the answer, you will find the remark
So it might print 49, or 56. Undefined behavior is, after all, undefined. This is why there is no real contradiction. You might want to brush up your understanding of what are called sequence points.
因为这是未定义的行为。编译器可以做任何它想做的事:它可以使代码打印 56、49 或“你的妈妈”,并且编译器仍然符合标准。
您不能在两个序列点之间多次修改同一值。
Because it's undefined behavior. The compiler can do whatever it wants: it can make the code print 56, 49, or "your mom", and the compiler would still be standards-conforming.
You can't modify the same value more than once between two sequence points.
表达式
i++ * i++
调用未定义的行为,因此任何结果都是可能的。为什么它是未定义的?因为语言标准是这样说的:
其中“未定义的行为”意味着
强调我的。
The expression
i++ * i++
invokes undefined behavior, so any result is possible.Why is it undefined? Because the language standard says so:
where "undefined behavior" means
Emphasis mine.
C-faq 真的这么说吗?您正在使用中间序列点修改变量 (
i
) 两次,这只会给出未定义的行为,仅此而已。它可以打印 49 或 56,或 73295,或什么也不打印,或“格式化硬盘驱动器...”(并继续执行该操作)。编辑:至于可能发生的情况,可以归结为:使用后增量,增量部分可以发生在检索值的时间和下一个序列点之间的任何位置。生成的代码可以很容易地像这样运行:
另一方面,它也可以像这样运行:
虽然这两者之一很可能,但标准并不强制要求其中任何一个。正如我上面所说,它是未定义的行为,这意味着 C 标准不会对代码的功能施加任何限制。
Does the C-faq really say that? You're modifying a variable (
i
) twice with an intervening sequence point, which simply gives undefined behavior, nothing more or less. It could print 49 or 56, or 73295, or nothing at all, or "Formatting hard drive..." (and proceed to do exactly that).Edit: As to what's likely to happen, it comes down to this: with a post-increment, the increment part can happen anywhere between the time you retrieve the value, and the next sequence point. The generated code could easily act like this:
On the other hand, it could also act like this:
While one of these two is likely, the standard doesn't mandate either one. As I said above, it's undefined behavior, which means the C standard doesn't place any limitation on what the code could do.