Неопределенное поведение или ложное срабатывание - PullRequest
3 голосов
/ 09 ноября 2010

Я (по существу) встречал следующее в дикой природе

x = x = 5;

, которая явно компилируется в более ранней версии gcc (генерирует предупреждение в gcc 4.5.1).Насколько я могу судить, предупреждение генерируется -Wsequence-point.Таким образом, мой вопрос заключается в том, нарушает ли это формулировку в стандарте о манипулировании переменными между точками последовательности (т. Е. Это неопределенное поведение в соответствии со спецификацией), или это неверный положительный результат gcc (то есть это определенное поведение в соответствии со спецификацией)?Трудно следовать формулировке пунктов последовательности.

Я сказал по существу, потому что то, что я действительно натолкнулся (в более широком выражении), было

x[0][0] = x[0][0] = 5;

, но я не думал, чтоБыл материал для предупреждения (пожалуйста, поправьте меня, если это не так, а я не понял, в чем суть вопроса).

1 Ответ

5 голосов
/ 09 ноября 2010

Предполагая, что x имеет встроенный тип, он присваивает x дважды без промежуточной точки последовательности, и это все, что вам нужно знать. Тот факт, что оба назначения имеют одно и то же значение (5) и теоретически может быть оптимизирован в одно назначение (если x не является изменчивым), ни здесь, ни там нет.

По крайней мере, так я интерпретирую «модифицированный» в стандарте - присваивает значение, независимо от того, совпадает ли оно со старым значением. Аналогично, отбрасывание const и присвоение объекту const, я думаю, является UB независимо от того, равно ли значение, которое вы назначаете, предыдущему значению. В противном случае это приведет к огромным накладным расходам на все операции записи в память, если реализация хочет поместить строковые литералы в ПЗУ, чтобы предотвратить ошибку страницы в этом случае, и мы знаем по проверке, что компиляторы не генерируют этот код.

Еще более интересным примером будет x[0][0] = x[0][i] = 5;, который назначает тому же объекту без промежуточной точки последовательности, если (и только если) i == 0, поэтому поведение определяется условным значением i.

Я не совсем понимаю, почему компилятор может сделать что-то неожиданное в любом случае, но опять же мое отсутствие воображения не имеет значения: -)

То, что умеет говорить, верно. Если вы находитесь в каком-то контексте, где вы не можете использовать два оператора, возможно, вместо этого напишите x[0][0] = 5, x[0][i] = 5. В обоих ваших случаях просто отбросьте избыточное назначение.

...