У меня есть такой код:
#include <stdio.h>
int main(int argc, char **argv) {
int i = 0;
(i+=10)+=10;
printf("i = %d\n", i);
return 0;
}
Если я попытаюсь скомпилировать его как источник C с помощью gcc, я получаю сообщение об ошибке:
error: lvalue required as left operand of assignment
Но если я скомпилирую его как источник C ++ с использованием g ++, я не получу ошибки, и когда я запускаю исполняемый файл:
i = 20
Почему другое поведение?
Ответы:
Семантика составных операторов присваивания различна в C и C ++:
Стандарт C99, 6.5.16, часть 3:
В C ++ 5.17.1:
EDIT: поведение
(i+=10)+=10
в C ++ не определено в C ++ 98, но хорошо определено в C ++ 11. См. Этот ответ на вопрос NPE для получения информации о соответствующих частях стандартов.источник
(i+=10)+=10
в C ++ поведение undefined, см. Ответ @aix.int f(int &y); f(x += 10);
- передача ссылки на измененную переменную в функцию.Помимо недопустимого кода C, строка
приведет к неопределенному поведению как в C, так и в C ++ 03, поскольку он будет
i
дважды изменяться между точками последовательности.Относительно того, почему разрешено компилировать на C ++:
В том же абзаце говорится, что
Это говорит о том, что в C ++ 11 выражение больше не имеет неопределенного поведения.
источник
i
которые не имеют последовательности.i = j+=1
бы неопределенное значение. Из того же абзаца вы цитируете: «Во всех случаях присваивание выполняется после вычисления значения правого и левого операндов, но перед вычислением значения выражения присваивания». Поэтому(i+=10)+=10
вполне определено делатьi += 10; i += 10;
. С другой стороны(i+=10)+=(i+=10)
- УБ.