c, побитовое, логическое выражение

int x = 0;
x^=x || x++ || ++x;

и, наконец, ответ для x равен 3. Как анализировать это выражение? немного запутался в этом. Большое спасибо.


c
person Josh Morrison    schedule 26.01.2011    source источник
comment
См .: stackoverflow.com/questions/1895922/ (вопрос предполагает знание точек последовательности) и stackoverflow.com/questions/4445706/ (см. принятый ответ). Не точные дубликаты, но этот UB хорошо покрыт SO.   -  person    schedule 27.01.2011
comment
См. Также Неопределенные точки поведения и последовательности. Это из c ++ - faq, но все еще применяется в целом.   -  person    schedule 27.01.2011


Ответы (4)


Это неопределенное поведение. Результат мог быть любым. Это связано с тем, что между ++x и x ^= нет точки последовательности, поэтому нет никакой гарантии, что будет "сделано" в первую очередь.

person Oliver Charlesworth    schedule 26.01.2011
comment
потому что что ? вы имеете в виду x ++, ++ x и так далее ... порядок вычислений не определен, верно? - person Josh Morrison; 27.01.2011
comment
@Andy, в частности, через ^=. - person Oliver Charlesworth; 27.01.2011
comment
Неправда, что нет точек последовательности: оператор || всегда является точкой последовательности. Единственные две модификации, вызывающие UB, - это последний ++x и x^=. - person aschepler; 27.01.2011
comment
@aschleper: Да, ты прав. Мой первоначальный ответ был мелкой оплошностью; Я сейчас это проясню. - person Oliver Charlesworth; 27.01.2011

Это неопределенное поведение - так что вы можете получить любой ответ, какой захотите.

person Carl Norum    schedule 26.01.2011
comment
Что ж, любой ответ, который захочет ваш компилятор. - person Oliver Charlesworth; 27.01.2011

Как уже отмечали другие, это неопределенное поведение. Но почему?

При программировании на C существует внутренняя разница между оператором и выражением. Оценка выражения должна дать вам те же наблюдаемые результаты в любом случае (например, (x + 5) + 2 совпадает с x + (5 + 2)). С другой стороны, операторы используются для определения последовательности побочных эффектов, то есть обычно приводят, скажем, к записи в какую-либо область памяти.

Учитывая вышеизложенное, выражения можно безопасно «вкладывать» в операторы, тогда как вложение операторов в выражения - нет. Под «безопасным» я подразумеваю «никаких удивительных результатов».

В вашем примере у нас есть

x^=x || x++ || ++x;

В каком порядке должна проводиться оценка? Поскольку || работает с выражениями, не имеет значения, идем ли мы (x || x ++) || ++ x или x || (x ++ || ++ x) или даже ++ x || (х || х ++). Однако, поскольку x ++ и ++ x являются операторами (даже несмотря на то, что C позволяет использовать их как выражения), мы не можем использовать алгебраические рассуждения. Итак, вам нужно будет явно выразить порядок операций, написав несколько операторов.

person Artyom Shalkhakov    schedule 27.01.2011

XOR 0 с 0 равно 0. Тогда ++ дважды равно 2. Тем не менее, как указано в других ответах, точки последовательности нет. Так что на выходе может быть что угодно.

person Ron    schedule 26.01.2011
comment
xor 0 с 0 на самом деле является 0. 0,0->0, 0,1->1, 1,0->1, 1,1->0. Это не лучшее начало для ответа :-) - person paxdiablo; 27.01.2011