Я читал в C ++ 17 Standard $ 8.5.7.4:
Выражение E1 секвенировано перед выражением E2.
для операторов смены.
Также в правиле 19 cppreference говорится:
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
Я получаю ожидаемый 320
как результат в обоих случаях (5 * 2 ^ 6)
Может кто-нибудь объяснить, почему я получаю это предупреждение? Я что-то упустил? Я также прочитал этот вопрос, связанный с этим не отвечаю на мой вопрос.
изменить: все другие варианты ++i << i
, i << ++i
и i << i++
приводят к тому же предупреждению.
edit2: (i << ++i)
приводит к 320
для clang (правильно) и 384
для gcc (неверно). Кажется, что gcc дает неправильный результат, если ++
находится на E2
, (i << i++)
также дает неправильный результат.
<<
, но, возможно, это было не раньше C ++ 14 или C ++ 17. Очевидно, что это ошибка, о которой в идеале следует сообщить. - person Cheers and hth. - Alf   schedule 10.08.2018160
в случае 5.++
выполняется после ‹---------------- - person RbMm   schedule 10.08.2018i++ << i
выполняется какi << i; i++
- person RbMm   schedule 10.08.2018g++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall
, я тоже получил это предупреждение, но когда я компилирую без флага-Wall
, я вообще не получал никакого предупреждения. Это может быть предупреждение о кодировании этого флага. Итак, поскольку это не неопределенное поведение С ++ 17, проблема, вероятно, связана с реализацией этого флага. - person CoralK   schedule 10.08.2018-Wall
, я получаю тот же неправильный результат с gcc для(i << ++i)
. clang выдает предупреждение также без-Wall
. - person mch   schedule 10.08.2018-fsanitize=undefined
и 160 с ним - person Tyker   schedule 10.08.2018