* * ++ я вызываю неопределенное поведение в C++03?

В другом ответе было указано, что до C++11, где i является int, затем используйте выражение:

*&++i

вызвало неопределенное поведение. Это правда?

На другом ответе было небольшое обсуждение в комментариях, но это кажется неубедительным.

2 ответа

Нет смысла спрашивать, *&++i сам по себе имеет UB. Ссылка не обязательно имеет доступ к сохраненному значению (предыдущему или новому) i, как вы можете видеть, используя это как выражение инициализатора для ссылки. Только если речь идет о преобразовании в значение (использование в таком контексте), возникает вопрос для обсуждения. И тогда, так как мы можем использовать значение ++iмы можем использовать значение *&++i с точно такими же оговорками, что и для ++i,

Первоначальный вопрос касался по существу i = ++i, который так же, как i = *&++i, Это было неопределенное поведение в C++03, из-за i изменяемый дважды между точками последовательности, и он четко определен в C++11 из-за побочных эффектов оператора присваивания, секвенируемого после вычисления значений левой и правой частей.

Возможно, уместно отметить, что ненормативные примеры в стандартах C++98 и C++ 03 были неверными, описывая некоторые случаи формально неопределенного поведения как просто неопределенное поведение. Таким образом, цель была не совсем ясна, все назад. Хорошее эмпирическое правило - просто не полагаться на такие неясные угловые случаи языка, чтобы избежать их: не нужно быть юристом по языку, чтобы разобраться в коде...

Я думаю, что вопрос имеет смысл, только если мы имеем дело с выражением:

i = *&++i;

Соответствующая цитата в стандарте C++03 будет [expr]/4:

Если не указано иное, порядок вычисления операндов отдельных операторов и подвыражений отдельных выражений и порядок возникновения побочных эффектов не определены. Между предыдущей и следующей точкой последовательности скалярному объекту должно быть изменено его сохраненное значение не более одного раза путем оценки выражения. Кроме того, предварительное значение должно быть доступно только для определения значения, которое будет сохранено. Требования этого параграфа должны выполняться для каждого допустимого упорядочения подвыражений полного выражения; в противном случае поведение не определено.

i = ++i + 1; // the behavior is unspecified

Мы можем просто сравнить последовательность i = *&++i против i = ++i + 1 определить, что одно и то же правило приводит к неопределенности обоих. Они оба являются утверждениями в форме:

i = f(++i);

Для любой функции fчтение i на левой стороне и побочный эффект ++i с правой стороны не секвенированы относительно друг друга. Следовательно, неопределенное поведение.

Другие вопросы по тегам