移位操作数在C ++ 17中排序

时间:2018-08-10 10:48:40

标签: c++ language-lawyer c++17 sequence-points

我读了C ++ 17 Standard $ 8.5.7.4:

  

表达式E1在表达式E2之前排序。

对于移位运算符。

cppreference规则19也说:

In a shift operator expression E1<<E2 and E1>>E2, every value
computation and side-effect of E1 is sequenced before every value
computation and side effect of E2

但是当我尝试使用gcc 7.3.0或clang 6.0.0编译以下代码时

#include <iostream>
using namespace std;

int main() {
    int i = 5;
    cout << (i++ << i) << endl;
    return 0;
}

我收到以下gcc警告:

../src/Cpp_shift.cpp: In function ‘int main()’:
../src/Cpp_shift.cpp:6:12: warning: operation on ‘i’ may be undefined [-Wsequence-point]
  cout << (i++ << i) << endl;
           ~^~

叮当警告是:

warning: unsequenced modification and access to 'i' [-Wunsequenced]

我使用以下命令进行编译:

g++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall
clang++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall

在两种情况下(5 * 2 ^ 6)我都得到预期的320输出

有人可以解释为什么我收到此警告吗?我有事吗我也阅读了this的相关问题,但没有回答我的问题。

编辑:所有其他变体++i << ii << ++ii << i++都会产生相同的警告。

edit2:(i << ++i)产生320的clang(正确),384产生gcc的(不正确)。如果++位于E2,gcc似乎给出了错误的结果,(i << i++)也给出了错误的结果。

1 个答案:

答案 0 :(得分:6)

标准清楚地说明了移位运算符的操作数的求值顺序。

n4659-§8.8(p4):

  

表达式E1在表达式E2之前排序。

表达式i++ << i中没有未定义的行为,定义明确。这是ClangGCC的错误。