表达式中的多个后缀增量运算符[C ++]

时间:2011-10-24 01:52:29

标签: c++

  

可能重复:
  Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

我现在正在上讲课,而我的讲师提到的表达方式如下:

int a , b;
a = 4;
b = a++ + a--;

问题

我的讲师说这个表达式值可以定义:它是8.这意味着值4被求和并在它递增和递减之前分配给b。

但是对我而言,我认为这个表达式的答案有点模糊,结果将基于编译器实现。这是因为对我来说,编译器可能首先执行a ++部分 - 也就是说,使用值4并将a增加到5,之后表达式为4 + 5 = 9并且分配给b然后只减少a。

它也可能首先使用值4来执行a--部分,然后将其递减1到3,然后将值4与3相加并将值赋值给b然后仅将a递增回4。

我的问题是谁是对的,我的讲师还是我?因为我不想与它混淆,后来对我来说将是一个问题。

1 个答案:

答案 0 :(得分:9)

你的讲师错了。在没有插入序列点的情况下写入相同的变量两次是未定义的行为。来自spec J.2未定义的行为

  

在两个序列点之间,对象被多次修改,或者被修改,并且读取先前值而不是确定要存储的值(6.5)。

引用的是 6.5表达式,第5段:

  

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。此外,先前的值应该是只读的,以确定要存储的值。

C规范的附录C有一个方便的所有序列点列表:

  

以下是5.1.2.3中描述的序列点:

     
      
  • 在评估参数(6.5.2.2)之后调用函数。
  •   
  • 以下运算符的第一个操作数的结尾:逻辑AND && (6.5.13);逻辑OR || (6.5.14);条件 ? (6.5.15);逗号 , (6.5.17)。
  •   
  • 完整声明者的结尾:声明者(6.7.5);
  •   
  • 完整表达式的结束:初始化程序(6.7.8);表达式中的表达式(6.8.3);选择语句的控制表达式( if switch )(6.8.4);控制表达 while do 声明(6.8.5); for 语句的每个表达式(6.8.5.3); return 语句(6.8.6.4)中的表达式。
  •   
  • 在库函数返回之前(7.1.4)。
  •   
  • 与每个格式化输入/输出函数转换说明符(7.19.6,7.24.2)相关联的操作之后。
  •   
  • 在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为参数传递给对象的任何移动之间(7.20.5)。
  •