Множественные операции преинкремента над переменной в C++(C?)
Почему следующее компилируется в C++?
int phew = 53;
++++++++++phew ;
Тот же код не работает в C, почему?
2 ответа
Это потому, что в C++
оператор предварительного приращения возвращает lvalue
и он требует, чтобы его операнд был lvalue
,
++++++++++phew ;
в интерпретации как ++(++(++(++(++phew))))
Однако ваш код вызывает Undefined Behaviour
потому что вы пытаетесь изменить значение phew
более одного раза между двумя точками последовательности.
В C
оператор предварительного приращения возвращает rvalue
и требует, чтобы его операнд был lvalue
, Таким образом, ваш код не компилируется в режиме C.
Примечание. Два отчета о дефектах DR#637 и DR#222 важны для понимания приведенного ниже объяснения поведения.
Для объяснения, в C++0x есть value computations
а также side effects
, Побочным эффектом, например, является присвоение, а вычисление значения определяет, что относится к значению lvalue или считывает значение из значения lvalue. Обратите внимание, что в C++0x больше нет точек последовательности, и этот материал сформулирован в терминах "секвенировано до" / "секвенировано после". И заявлено, что
Если побочный эффект на скалярный объект не секвенирован относительно другого побочного эффекта на тот же скалярный объект или вычисления значения с использованием значения того же скалярного объекта, поведение не определено.
++v
эквивалентно v += 1
что эквивалентно v = v + 1
(за исключением того, что v оценивается только один раз). Это дает ++ (v = v + 1)
который я напишу как inc = inc + 1
, где inc
относится к lvalue результату v = v + 1
,
В C++0x ++ ++v
не неопределенное поведение, потому что для a = b
присваивание выполняется после вычисления значения b и a, но перед вычислением значения выражения присваивания. Отсюда следует, что присвоение в v = v + 1
последовательность перед вычислением значения inc
, И назначение в inc = inc + 1
секвенируется после вычисления значения inc
, В итоге оба назначения будут упорядочены, и не будет неопределенного поведения.