Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
184 views
in Technique[技术] by (71.8m points)

c++ - Shift operands sequenced in C++17

I read in the C++17 Standard $8.5.7.4:

The expression E1 is sequenced before the expression E2.

for shift operators.

Also cppreference rule 19 says:

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

But when I try to compile the following code with gcc 7.3.0 or clang 6.0.0

#include <iostream>
using namespace std;

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

I get the following gcc warning:

../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;
           ~^~

The clang warning is:

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

I used the following commands to compile:

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

I get the expected 320 as output in both cases ( 5 * 2 ^ 6 )

Can someone explain why I get this warning? Did I overlook something? I also read this related question, but it does not answer my question.

edit: all other variants ++i << i, i << ++i and i << i++ result in the same warning.

edit2: (i << ++i) results in 320 for clang (correct) and 384 for gcc (incorrect). It seems that gcc gives a wrong result if the ++ is at E2, (i << i++) also gives a wrong result.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Standard is clear about the order of evaluation of the operands of the shift operator.

n4659 - §8.8 (p4):

The expression E1 is sequenced before the expression E2.

There is no undefined behavior in the expression i++ << i, it is well defined. It is a bug in Clang and GCC both.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...