【问题标题】:Addition and Increment expression in [ ] - operator[]中的加法和增量表达式 - 运算符
【发布时间】:2017-01-31 18:27:06
【问题描述】:

根据标准,以下两个表达式是未定义的行为吗?

int a = 1, b = 1; 
int c[] = { 1, 2, 3, 4, 5 }; 

// Do the following expressions lead to Undefined Behavior ? 
c[a++]; // (1)  
c[a+b]; // (2) 

【问题讨论】:

  • a 不是数组......
  • a[a++]; 是编译器错误
  • 你的意思是int c[] = { 1, 2, 3, 4, 5 };
  • 为了理解这个问题,您应该解释为什么您认为它可能是 UB。
  • @MichaelDorgan:没有收到警告并不能保证没有 UB。

标签: c++ c++11 undefined-behavior iso


【解决方案1】:

不,以目前的形式,它们不会导致未定义的行为。没有您可能担心的序列点违规。

  • c[a++]; 的情况下,a 的现有值用于索引,a 作为副作用(后增量运算符)递增。
  • c[a+b]; 没有任何变量值被更改a+b 是数组的有效索引。

【讨论】:

  • c++14 iso 标准部分1.9.15 中有一个示例导致混淆:open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf 但我可能只是误解了该部分。
  • @SebNag 该示例使用v[i++] 的结果来更改i,这会产生i 的两个未排序的修改。顺便说一句,C++14 标准将是 N4141(+- 一些错字/布局修复可能)。 N4296 是中间草案。
  • @SebNag 这是另一种情况,您在i 上使用后增量以及将RHS 值分配回i。现在,执行副作用和赋值之间没有顺序点,问题出在哪里。
  • @BaummitAugen 跑题了,只是问一下,后面的版本是草稿??
  • @SouravGhosh 这是第一个 C++17 草案 afaik。现在我想起来了,我不确定它是否包含与 C++14 相比的任何更改,但 N4141 是正常的 C++14 源 afaik。
【解决方案2】:

如果 a 或 b 或 a 和 b 的总和大于数组的大小,您可能会得到未定义的行为:

int a = 1, b = 1; 
int c[] = { 1, 2, 3, 4, 5 }; 

c[a++]; // (1)  a = 2
c[a+b]; // (2) a + b = 3

cout << c[a] << endl;   // 3
cout << c[a+b] << endl; // 4
cout << a << ", " << b << endl;

如您所见,没有 UB,因为 c[a + b] = c[3] 是数组的一个元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    相关资源
    最近更新 更多