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

mch*_*mch 13 c++ sequence-points language-lawyer c++17

我读了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
Run Code Online (Sandbox Code Playgroud)

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

#include <iostream>
using namespace std;

int main() {
    int i = 5;
    cout << (i++ << i) << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到以下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;
           ~^~
Run Code Online (Sandbox Code Playgroud)

铿锵警告是:

warning: unsequenced modification and access to 'i' [-Wunsequenced]
Run Code Online (Sandbox Code Playgroud)

我使用以下命令编译:

g++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall
clang++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall
Run Code Online (Sandbox Code Playgroud)

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

有人可以解释为什么我会收到此警告吗?我忽略了什么吗?我也读过这个相关的问题,但它没有回答我的问题.

编辑:所有其他变体++i << i,i << ++ii << i++导致相同的警告.

edit2:(i << ++i)结果320为clang(正确)和384gcc(不正确).似乎gcc给出了错误的结果,如果++它处于E2,(i << i++)也会给出错误的结果.

hac*_*cks 6

标准清楚地表明了移位运算符的操作数的评估顺序.

n4659 - §8.8(p4):

表达式E1在表达之前进行测序E2.

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

  • 明确:错误的质量诊断,不一定是不合格的错误.在诊断更新之前,可以修复实际的运行时行为以符合C++ 17. (4认同)
  • 令人惊讶的是,他们在这样一个基本上易于测试的变化上都是错误的 - 不只是诊断而是实际结果. (2认同)