是foo(我+ +)+富(我++)未定义的ANSI C? [英] Is foo(i++) + foo(i++) undefined in ANSI C?

查看:117
本文介绍了是foo(我+ +)+富(我++)未定义的ANSI C?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个例子片断:

int i = 4,b;    
b = foo(i++) + foo(i++);

我是pretty确定它的不可以未定义的,因为有一个序列点的调用之前。但是,如果我编译code。与生成编译器警告 -Wall 标志,它说警告:操作上的'我'可能未定义。我知道它说可以,但我只是想仔细检查,如果我是正确的。

I'm pretty certain it's not undefined, because there is a sequence point before the invocation of foo. However, if I compile the code with the -Wall flag a compiler warning is generated which says warning: operation on 'i' may be undefined. I realize it says may, but I'd just like to double check if I'm correct.

推荐答案

的行为是不确定的。

b = foo(i++) + foo(i++);

正如你所说,有第一个的评价之间的序列点i ++ 并调用,第二的评价之间同样我++ 和呼叫。但目前还没有(不一定)的两次评价之间的序列点i ++ ,或者更具体地说其副作用(修改的 I )。

As you say, there's a sequence point between the evaluation of the first i++ and the call to foo, and likewise between the evaluation of the second i++ and the call foo. But there isn't (necessarily) a sequence point between the two evaluations of i++, or more specifically between their side effects (modifying i).

引述 N1570 2011年的ISO C标准的草案,部分6.5.2.2p10:

Quoting the N1570 draft of the 2011 ISO C standard, section 6.5.2.2p10:

有是函数的评价后的序列点
  标志和实际参数,但实际的呼叫。一切
  评估调用函数(包括其它函数调用)
  不是之前或之后,另有具体测序
  被调用的函数的主体的执行是indeterminately
  测序相对于被调用函数的执行。

There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

第二句话是显著的位置:的两个评价我++ 是indeterminately
测序相对于这两个函数调用,这意味着它们可以之前或调用后发生。(他们没有的 unsequenced 的虽然;他们每个人发生之前或来电之后,但它是不明其中)

The second sentence is significant here: the two evaluations of i++ are "indeterminately sequenced" with respect to the two function calls, meaning that they can occur either before or after the calls to foo. (They're not unsequenced, though; each of them occurs either before or after the calls, but it's unspecified which.)

和6.5p2说:

如果一个标物体上的副作用是相对于unsequenced任
  同样标对象或值在不同的副作用
  使用同一个标量对象的值计算,该行为是
  未定义。如果有的多个容许序
  SUBEX $一名前pression的对$ pssions,行为是不确定的,如果这样的
  unsequenced副作用发生在任何一个排序的。

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

把这个在一起,一个符合标准的实现可以在这个为了评估前pression:

Putting this together, a conforming implementation could evaluate the expression in this order:


  1. 评估第一个我++ 和保存在某个地方的价值。

  2. 评估第二个我++ 和保存在某个地方的价值。

  3. 呼叫,路过的第一个保存的值作为参数。<​​/ li>
  4. 呼叫,传递第二个保存的值作为参数。<​​/ li>
  5. 添加两个结果。

  6. 存储在的总和b

  1. Evaluate the first i++ and save the value somewhere.
  2. Evaluate the second i++and save the value somewhere.
  3. Call foo, passing the first saved value as an argument.
  4. Call foo, passing the second saved value as an argument.
  5. Add the two results.
  6. Store the sum in b.

有步骤1和2,这两个修改 I 之间没有顺序点,这样的行为是不确定的。

There is no sequence point between steps 1 and 2, both of which modify i, so the behavior is undefined.

(这实际上是一个轻微的过于简单;修改 I 可以从的结果,我++

(That's actually a slight oversimplification; the side effect of modifying i can be separated from the determination of the result of i++.

底线:我们知道,

b = i++ + i++;

是未定义行为,已多次解释的原因。包裹我++ SUBEX $ P $函数调用pssions确实增加了一些序列点,但这些序列点不的两个评价单独的I ++ 并且因此不会导致行为变得良好定义

has undefined behavior, for reasons that have been explained repeatedly. Wrapping the i++ subexpressions in function calls does add some sequence points, but those sequence points don't separate the two evaluations of i++ and therefore don't cause the behavior to become well defined.

即使bottommer行:请不要写code这样。即使行为进行了明确界定,这将是更困难比它的价值来证明这一点,并确定该行为应该是什么。

Even bottommer line: Please don't write code like that. Even if the behavior were well defined, it would be more difficult than it's worth to prove it and to determine what the behavior should be.

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

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