Несколько операций preincrement для переменной в С++ (C?)

Почему следующая компиляция в С++?

int phew = 53;
++++++++++phew ;

Тот же код не работает в C, почему?

Ответ 1

Это потому, что в C++ оператор pre-increment возвращает lvalue и требует, чтобы его операнд был lvalue.

++++++++++phew ; интерпретируется как ++(++(++(++(++phew))))

Однако ваш код вызывает Undefined Behaviour, потому что вы пытаетесь изменить значение phew более одного раза между двумя точками последовательности.

В C оператор pre-increment возвращает rvalue и требует, чтобы его операнд был lvalue. Таким образом, ваш код не компилируется в режиме C.

Ответ 2

Примечание. Два отчета об ошибках DR # 637 и DR # 222 важны для понимания объяснения поведения ниже.


Для объяснения в С++ 0x есть value computations и side effects. Например, побочным эффектом является привязка, и вычисление значения определяет, что означает lvalue или считывает значение из lvalue. Обратите внимание, что С++ 0x больше не имеет точек последовательности, и этот материал сформулирован в терминах "sequenced before" / "sequenced after". И сказано, что

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

++v эквивалентен v += 1, который эквивалентен v = v + 1 (за исключением того, что v оценивается только один раз). Это дает ++ (v = v + 1), который я напишу как inc = inc + 1, где inc ссылается на результат lvalue v = v + 1.

В С++ 0x ++ ++v не работает undefined, потому что для a = b присваивание упорядочивается после вычисления значения b и a, но до вычисления значения выражения присваивания. Из этого следует, что присвоение в v = v + 1 секвенировано перед вычислением значения inc. И назначение в inc = inc + 1 секвенируется после вычисления значения inc. В итоге оба назначения будут, таким образом, секвенированы, и не будет поведения undefined.