Предполагая, что 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
. В обоих ваших случаях просто отбросьте избыточное назначение.