2015-03-28 1 views
6

Я все еще не мог четко понять, является ли выражение x ^= y ^= x ^= y; действительным в C++ 11 (как говорится в этом thread) или приводит к неопределенному поведению?Обмен целыми числами через XOR в одной строке. Действительно ли это разрешено в C++ 11?

Причина, по ссылке кажется убедительной, но лязг бросает warning:

предупреждения: unsequenced модификации и доступ к 'х' [-Wunsequenced]

Кроме того, если оба версий :

x ^= y ^= x ^= y; // (1) 
x = x^(y = y^(x = (x^y))); // (2) 

считаются эквивалентными (и хорошо определены в C++ 11), поэтому он дает различные результаты (first, second)?

Кроме того, следует отметить, что gcc дает warning о точке последовательности только на второй версии кода.

+2

Нет, это не определено. Анализ очень похож на анализ 'i + = ++ i + 1' в [этот вопрос] (http://stackoverflow.com/questions/24194076/in-c11-does-ii-1-exhibit-undefined- поведение). –

+0

эти версии не эквивалентны вообще. – UmNyobe

+1

См. Http://stackoverflow.com/questions/29313902/sequence-point-within-assignment-operators – Lingxi

ответ

11

Оператор присваивания (=) и составные операторы присваивания все группа справа налево. [..]
Поведение выражения вида E1 op = E2 эквивалентно E1 = E1 op E2, за исключением того, что E1 - оценивается только один раз.

Таким образом, ваш код эквивалентен

x = x^(y ^= (x ^= y))); 

... с й вычисляются только один раз в x = x .... К сожалению, для xor, оценка операндов не имеет последствий. То есть

За исключением тех случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражений не имеют последствий.

применяется. Но теперь у нас есть проблема:

x = x^(y ^= (x ^= y))); 
//  *   ****** 
//  |   | 
//  |   Side effect 
//  Value computation 

Вычисление значения (которое подразумевается в особых оценках x для двух левых x) и побочного эффект являются unsequenced WRT друг друга, поэтому мы индуцируем UB:

Если побочный эффект от скалярного объекта unsequenced по отношению к любой другой побочный эффект на той же скалярного объекта или вычисления значения с использованием значения одного и того же скалярного объекта, поведение не определено.

+1

, но он по-прежнему не отвечает, если первая версия UB или нет. – sp2danny

+0

@ sp2danny. Вы читали мой ответ? – Columbo

+0

im, начинающий склоняться к обеим конструкциям, являющимся UB – sp2danny