2016-03-25 8 views
1

Являются ли постфиксные и префиксы приращениями и декрементами lvalues ​​в C11? Обычно в стандарте есть примечания внизу, указывающие, является ли данное выражение значением lvalue. В этом случае я не могу найти ничего в стандарте.Являются ли постфиксные и префиксные приращения и декременты выражения lvalues ​​в C11?

Я знаю, что в большинстве случаев будут проблемы с точкой последовательности, но есть некоторые случаи кросс, где кажется, что было бы полезно знать это. Например, в 6.5.2.4:

Postfix ++ для объекта с атомным типом является операцией чтения-изменения-записи с семантикой памяти memory_order_seq_cst.

Из этого следует, что с атомным типом что-то вроде ++ x = x + y будет явным способом сделать что-то. Не то чтобы было важно быть в состоянии сделать что-то такое, мне просто не нравится, когда я ничего не знаю.

+1

Даже если они были lvalues, их изменение может привести к неопределенному поведению для многократного изменения объекта между точками последовательности. – EOF

+0

Есть ли определенное правило против этого? Было бы разумно делать такую ​​вещь с атомными типами. – Kyle

+0

C11 draft standard n1570: * 6.5 Выражения 2 Если побочный эффект скалярного объекта не зависит от другого побочного эффекта на том же скалярном объекте или вычисления значения с использованием значения одного и того же скалярного объекта, поведение не определено. [...] * – EOF

ответ

5

Этот аспект поведения операторов приращения и уменьшения префиксов и префиксов определяется частью стандартного документа, посвященного аддитивным операторам и операторам присваивания.

В случае операторов постфиксных

[...] См дискуссии операторов аддитивных и назначения соединения для информации об ограничениях, типах и преобразовании [...]

в случае префикс (одинарные) операторов

[...] выражение ++ Е эквивалентно (E + = 1) [...]

(Последнее является более прямым, чем первый, но цель в отношении именующей-ности результата будет то же самое.)

выражение присваивания в C не является именующим

Выражение присваивания имеет значение левого операнда после назначения, но не является значением lvalue.

В качестве побочного примечания это одно из глубоких фундаментальных различий между C и C++ языками: C++ - язык, сохраняющий lvalue, а C - язык, отбрасывающий lvalue.