Является ли `(i) = 1` незаконным в стандарте C? - PullRequest
8 голосов
/ 12 октября 2019

Я пишу компилятор C, который следует этому стандарту , и если я анализирую операторы следующим образом:

int i;
(i) = 1;

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

Я проверил код и правила и обнаружил следующее: в семантике выражения присваивания:

Оператор присваивания должен иметь модифицируемое значение lvalueкак его левый операнд.

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

В моем случае существует два выражения присваивания: (i) = 1 и i в скобках. Таким образом, (i) должно быть значением.

Итак, мой вопрос: является ли (i) = 1 незаконным в этом стандарте C?

Ответы [ 3 ]

8 голосов
/ 12 октября 2019

Цитировать n1570 (последний черновик стандарта C11 перед публикацией):

6.5.1 Первичные выражения (выделение мое)

5 Выражение в скобках является основным выражением. Его тип и значение идентичны типам выражения без скобок . Это lvalue, обозначение функции или выражение void, если выражение без скобок является, соответственно, lvalue, указателем функции или выражением void.

i является lvalue, поэтомув соответствии с вышеизложенным - (i). И чтобы ответить на ваш вопрос, выражение (i) = 1 является действительным C.

0 голосов
/ 14 октября 2019

Этот ответ вдохновлен @Eric Postpischil.

Производство assignment-expression - это:

<assignment-expression> ::= <conditional-expression>
                          | <unary-expression> <assignment-operator> <assignment-expression>

в стандарте, assignment expression специальные выражения означает с операторами присваивания,Итак:

<conditional-expression> is not an assignment expression
<unary-expression> <assignment-operator> <assignment-expression> is an assignment expresssion

, поэтому правило:

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

подходит только для производства <unary-expression> <assignment-operator> <assignment-expression>, но не для <conditional-expression>

в примере (i) =1, i - это <assignment-expression>, но не assignment expression, это <conditional-expression>так что это lvaule так что (i) это lvalue.

0 голосов
/ 12 октября 2019

StoryTeller уже объяснил, где в стандарте почему для вашего примера выражение (i) по-прежнему является lvalue, но я полагаю, что вы зациклены на спецификации без причины, поэтому позвольте мне попытаться решить ваши проблемы.

Я проверил код и правила и обнаружил следующее: в семантике выражения присваивания:

Оператор присваивания должен иметь изменяемое значение lvalue в качестве своего левого операнда.

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

Вся кавычка относится к выражению присваивания в целом, а не кlhs или rhs.

«Оператор присваивания должен иметь изменяемое lvalue в качестве своего левого операнда». утверждает, что lhs должен быть изменяемым lvalue.

«Выражение присваивания имеет значение левого операнда после присваивания, но не является lvalue». заявляет, что само выражение присваивания в результате имеет значение lhs и само является rvalue.

Итак, все верно следующее:

int i;
  i <- modifiable lvalue

(i) = 1;
  (i) <- modifiable lvalue (per StoryTeller's answer)
  1 <- rvalue
  ((i) = 1) <- rvalue

Почему это важно? Рассмотрим следующее:

int i = 0, j = 0, k = 0;
i = j = k = 1;
// parsed as `i = (j = (k = 1))`
// the expression `k = 1` has the value `1` and is an rvalue
// the expression `j = (k = 1)` has the value `1` and is an rvalue

(i = 2) = 3;
// is invalid, the expression `i = 2` is an rvalue, but it may not be the lhs of the assignment

В моем случае существует два выражения присваивания: (i) = 1 и i в скобках. Таким образом, (i) должно быть значением.

Нет, это неверно. (i) = 1 является единственным выражением присваивания. Существует два подвыражения (один заключенный в скобки идентификатор (i) и числовая константа 1).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...