¿Es `(i) = 1` ilegal en el estándar C?

8

Estoy escribiendo un compilador de C que sigue este estándar , y si analizo declaraciones como esta:

int i;
(i) = 1;

mi compilador informará un error que señala que (i)es un valor r y no debe ser asignable.

Revisé el código y las reglas, y encontré esto: en la semántica de expresiones de asignación:

Un operador de asignación tendrá un valor l modificable como su operando izquierdo.

Una expresión de asignación tiene el valor del operando izquierdo después de la asignación, pero no es un valor l.

En mi caso, hay dos expresiones de asignación: (i) = 1y ientre paréntesis. Entonces (i)debería ser un valor r.

Entonces mi pregunta es: ¿es (i) = 1ilegal en este estándar C?

ravenisadesk
fuente
1
Sigue siendo un valor, los paréntesis no cambian eso.
Jeff Mercado
1
Hola a todos, indiquen qué regla en el estándar si es legal, mi compilador sigue rigurosamente la regla.
ravenisadesk
ientre paréntesis no es una expresión de asignación. La expresión de asignación no significa "expresión involucrada en una asignación" o cualquier otra cosa (i)que califique. Las expresiones de asignación son asignaciones .
user2357112 es compatible con Monica el
@ user2357112 ies una expresión de asignación, el árbol AST se expresión-> ASSIGNMENT_EXPRESSION-> CONDITIONAL_EXPRESSION-> LOGICAL_OR_EXPRESSION-> CAST_EXPRESSION-> UNARY_EXPRESSION-> POSTFIX_EXPRESSION-> PRIMARY_EXPRESSION-> IDENTIFICADOR
ravenisadesk
@reavenisadesk: una assignment-expressiongramática no terminal no es lo mismo que una expresión de asignación. Aproximadamente, un assignment-expressiones una expresión de asignación o cualquier cosa con mayor precedencia.
user2357112 es compatible con Monica el

Respuestas:

8

Para citar n1570 (el último borrador estándar de C11 antes de la publicación):

6.5.1 Expresiones primarias (énfasis mío)

5 Una expresión entre paréntesis es una expresión primaria. Su tipo y valor son idénticos a los de la expresión sin paréntesis . Es un valor de l, un designador de función o una expresión vacía si la expresión sin paréntesis es, respectivamente, un valor de l, un designador de función o una expresión vacía.

ies un valor de l, así que por lo anterior también lo es (i). Y para responder a su pregunta, la expresión (i) = 1es válida C.

StoryTeller - Unslander Monica
fuente
Tengo problemas, veamos el BNF de la expresión primaria entre paréntesis ( expression ), por lo que el tipo y el valor son idénticos a expression, y expressiones un assignment expression, y el assignment expressiones un primary expression, simplemente, ise tratará como assignment expressional final, por lo que debe seguir la regla de assignment expressionat Por último, creo que debería ser un valor.
ravenisadesk
1
@reavenisadesk - Excepto que claramente, negro sobre blanco, no es un valor. ¿O estás diciendo i = 1que no es válido también?
StoryTeller - Unslander Monica
Creo que i = 1es válido debido a esto: assignment-expression: unary-expression assignment-operator assignment-expressionen el caso i = 1, me tratan como unary-expression, lo cual es un valor, no assignment expression, creo que su i = 1ejemplo no es el caso.
ravenisadesk
2
@reavenisadesk: La gramática no dice qué cosas son valores o valores. La semántica sí. Para una expresión de asignación, C 6.5.16 3 (justo debajo del encabezado "Semántica") dice una expresión de asignación (que es una frase que describe la expresión formada con un operador de asignación, no una expresión de asignación , que es un token en la gramática ) no es un valor. No dice que el token de gramática de expresión de asignación no es un valor l.
Eric Postpischil
1
@reavenisadesk - Eric lo explicó con mucha más elocuencia que yo. Además, me parece que te estás metiendo (i)injustamente aquí. El mismo punto sobre la semántica se aplica a todo tipo de expresión.
StoryTeller - Unslander Monica
0

StoryTeller ya explicó en qué parte del estándar por qué, para su ejemplo, la expresión (i)sigue siendo un valor, pero creo que está colgado en la especificación sin ningún motivo, así que permítame tratar de abordar sus inquietudes.

Revisé el código y las reglas, y encontré esto: en la semántica de expresiones de asignación:

Un operador de asignación tendrá un valor l modificable como su operando izquierdo.

Una expresión de asignación tiene el valor del operando izquierdo después de la asignación, pero no es un valor l.

La cita completa se refiere a la expresión de asignación como un todo, no a lhs o rhs.

"Un operador de asignación tendrá un valor l modificable como su operando izquierdo". establece que lhs debe ser un valor l modificable.

"Una expresión de asignación tiene el valor del operando izquierdo después de la asignación, pero no es un valor l". establece que toda la expresión de asignación en sí misma como resultado tiene el valor de lhs y es en sí misma un valor r.

Entonces, lo siguiente es cierto:

int i;
  i <- modifiable lvalue

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

¿Por qué es esto significativo? Considera lo siguiente:

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

En mi caso, hay dos expresiones de asignación: (i) = 1y ientre paréntesis. Entonces (i)debería ser un valor r.

No, eso es incorrecto. (i) = 1es la única expresión de asignación. Hay dos subexpresiones (un identificador entre paréntesis (i)y una constante numérica 1).

Jeff Mercado
fuente
0

Esta respuesta está inspirada en @Eric Postpischil.

la producción de a assignment-expressiones:

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

en el estándar, las assignment expressionexpresiones de medios específicos con operadores de asignación. Entonces:

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

entonces la regla:

Una expresión de asignación tiene el valor del operando izquierdo después de la asignación, pero no es un valor l.

solo se ajusta a la producción <unary-expression> <assignment-operator> <assignment-expression>, no a<conditional-expression>

en el ejemplo (i) =1, ies un <assignment-expression>pero no un assignment expression, es un, <conditional-expression>así que es un valor, así (i)es un valor.

ravenisadesk
fuente