是的printf的输出(QUOT;%D",C ++,C);也未定义? [英] Is the output of printf ("%d %d", c++, c); also undefined?

查看:136
本文介绍了是的printf的输出(QUOT;%D",C ++,C);也未定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近碰到一个帖子什么是COUT正确答案<< C ++<< Ç;?,想知道是否输出

  INT C = 0;
的printf(%D,C ++,C);

也是不确定的?

我已经研究在得到一个分号修复后和preFIX运营商增值后才讲座。所以根据我来说,输出 0 是正确的!


解决方案

  

我已经研究了讲座。修复后和preFIX运营商增值只得到一个分号了。


发送您的讲师给我,让我能<击>拿棒球棒给他客气地指出他的错误。

究竟何时 ++ 无论是pre或后缀的副作用 - 应用是的未指定的,除了它的下一个序列点之前发生的要求。在一个前pression像

  X = A ++ * B

A 可在 A ++立即更新进行了评估,或更新可能会被推迟,直到 A ++ * b 已评估并分配给 X ,或之间的任何地方。

这也是为什么前pressions像我++ * i ++在的printf(%D,C ++,C) A [I +] =我和其他的主机都是坏朱朱。您将根据编译器,优化设置得到不同的结果,周围code等语言标准明确地离开行为的未定义的这样编译器没有义务为做正确的事,不管正确的事情而定。记住,为了使定义的未定义行为的是


3.4.3


1 理解过程网络斯内德行为的结果
行为,或者在错误数据的使用不可移植的或错误的程序构造,
对于这本国际标准并没有规定要求的搜索结果
2注意可能的理解过程网络斯内德从行为与联合国predictable完全无视的情况范围
结果,在的一个记录方式的特点翻译或程序执行过程中的行为
环境(有或没有发出一个诊断消息),以终止翻译或
执行(并出具诊断消息)。搜索结果
3例的理解过程网络斯内德行为的一个例子是溢流整数的行为。

这是一个经过深思熟虑的设计决定 - 离开的这些操作未指定顺序的理由是给实施自由地重新优化的目的评估顺序。然而,换来的自由,某些操作不会有明确定义的结果。

注意,编译器是免费的尝试的检测到这些情况,并出具诊断; 的printf(%D,C ++,C); 将是很容易赶上,但是这将是一个鸡奸在一般情况下,检测。如果已经写想象的printf(%D(* P)++,C);如果 P C ,则行为是不确定的,否则也没关系。如果 P 在不同的翻译单元分配的,那么有没有办法在编译时知道这是否是一个问题或没有。

这概念并不难理解,但它是最一致的误解之一(误的)C语言的各个方面。毫无疑问,这就是为什么Java和C#语言规范强制具体的评价为了一切(所有操作数是从左向右,所有副作用立即应用)。

I recently came across a post What is the correct answer for cout << c++ << c;? and was wondering whether the output of

int c = 0;  
printf ("%d %d", c++, c);  

is also undefined??

I have studied in lectures that post-fix and prefix operators increment value only after getting a semicolon. So according to me, the output 0 0 is correct !!!

解决方案

I have studied in lectures that post-fix and prefix operators increment value only after getting a semicolon.

Send your lecturer to me so that I can take a baseball bat to him politely point out his mistake.

Exactly when the side effect of either pre- or postfix ++ and -- is applied is unspecified, apart from the requirement that it happen before the next sequence point. In an expression like

x = a++ * b

a may be updated immediately after a++ has been evaluated, or the update may be deferred until a++ * b has been evaluated and the result assigned to x, or anywhere in between.

This is why expressions like i++ * i++ and printf("%d %d", c++, c) and a[i++] = i and a host of others are all bad juju. You will get different results based on the compiler, optimization settings, surrounding code, etc. The language standard explicitly leaves the behavior undefined so that the compiler is under no obligation to "do the right thing", whatever the right thing may be. Remember, the definition for undefined behavior is

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.

This is a deliberate design decision - the rationale for leaving the order of these operations unspecified is to give the implementation freedom to rearrange the evaluation order for optimization purposes. However, in exchange for this freedom, certain operations will not have well-defined results.

Note that a compiler is free to try to detect these cases and issue a diagnostic; printf("%d %d", c++, c); would be easy enough to catch, but this would be a bugger to detect in the general case. Imagine if that had been written printf("%d %d", (*p)++, c); if p points to c, then the behavior is undefined, otherwise it's okay. If p is assigned in a different translation unit, then there's no way to know at compile time whether this is a problem or not.

This concept is not difficult to understand, yet it is one of the most consistently misunderstood (and mis-taught) aspects of the C language. No doubt this is why the Java and C# language specifications force a specific evaluation order for everything (all operands are evaluated left-to-right, and all side effects are applied immediately).

这篇关于是的printf的输出(QUOT;%D&QUOT;,C ++,C);也未定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆