Несколько операций 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.