Очки последовательности - это g cc предупреждение об ошибке? - PullRequest
7 голосов
/ 30 марта 2020

Возьми эту игрушечную программу:

int main() 
{
  int a = 1;
  a = ++a ;
}

Компиляция под g cc 9.3 (или даже транк) с -Wall -std=c++17 выходами:

<source>:4:5: warning: operation on 'a' may be undefined [-Wsequence-point]
    4 |   a = ++a ;
      |   ~~^~~~~

Я знаю, что в прошлом это действительно была проблема, но другой ответ на тот же вопрос SO указывает на ту часть стандарта C ++ 17, которая была исправлена ​​на указать, что в операциях присваивания rhs секвенируется перед фактическим присвоением:

8.18. ... Во всех случаях присваивание выполняется после вычисления значения правого и левого операндов и перед вычислением значения выражения присваивания.

Так что это предупреждение действительно поддельное или я чего-то не хватает?

Ответы [ 2 ]

8 голосов
/ 30 марта 2020

Да, это ошибка. За [expr.ass] / 1

Оператор присваивания (=) и составные операторы присваивания все группы справа налево. Все они требуют изменяемого lvalue в качестве своего левого операнда и возвращают lvalue, ссылаясь на левый операнд. Результатом во всех случаях является битовое поле, если левый операнд является битовым полем. Во всех случаях присвоение упорядочивается после вычисления значения правого и левого операндов и до вычисления значения выражения присваивания. Правый операнд упорядочен перед левым операндом. Что касается вызова функции с неопределенной последовательностью, операция составного присваивания является единственной оценкой. [Примечание: Поэтому вызов функции не должен вмешиваться между преобразованием lvalue-to-rvalue и побочным эффектом, связанным с каким-либо одним составным оператором присваивания. - конец примечания]

выделение мин

Теперь существует точка последовательности между приращением и назначением, и код имеет хорошо определенное поведение. Их эвристика предупреждений должна быть обновлена, чтобы учесть эту новую функцию.

4 голосов
/ 31 марта 2020

Как уже упоминалось в другом ответе, код хорошо себя ведет и сообщение является ложноположительным для C ++ 17, но я хочу добавить, что G CC намеренно все еще предупреждает об этом.

Документация G CC указывает на флаг предупреждения -Wsequence-point (активируется -Wall):

Стандарт C ++ 17 будет определять порядок оценки операндов в большем количестве случаев: в частности, требуется, чтобы правая часть присваивания была оценена перед левой, поэтому приведенные выше примеры больше не являются неопределенными. Но эта опция все равно будет предупреждать о них, чтобы помочь людям избежать написания кода, который не определен в C и более ранних версиях C ++.

Таким образом, предполагается, что эта программа выдаст это предупреждение.

...