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) = 1
y i
entre paréntesis. Entonces (i)
debería ser un valor r.
Entonces mi pregunta es: ¿es
(i) = 1
ilegal en este estándar C?
c
language-lawyer
variable-assignment
rvalue
lvalue-to-rvalue
ravenisadesk
fuente
fuente
i
entre 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 .i
es 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-> IDENTIFICADORassignment-expression
gramática no terminal no es lo mismo que una expresión de asignación. Aproximadamente, unassignment-expression
es una expresión de asignación o cualquier cosa con mayor precedencia.Respuestas:
Para citar n1570 (el último borrador estándar de C11 antes de la publicación):
i
es un valor de l, así que por lo anterior también lo es(i)
. Y para responder a su pregunta, la expresión(i) = 1
es válida C.fuente
( expression )
, por lo que el tipo y el valor son idénticos aexpression
, yexpression
es unassignment expression
, y elassignment expression
es unprimary expression
, simplemente,i
se tratará comoassignment expression
al final, por lo que debe seguir la regla deassignment expression
at Por último, creo que debería ser un valor.i = 1
que no es válido también?i = 1
es válido debido a esto:assignment-expression: unary-expression assignment-operator assignment-expression
en el casoi = 1
, me tratan comounary-expression
, lo cual es un valor, noassignment expression
, creo que sui = 1
ejemplo no es el caso.(i)
injustamente aquí. El mismo punto sobre la semántica se aplica a todo tipo de expresión.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.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:
¿Por qué es esto significativo? Considera lo siguiente:
No, eso es incorrecto.
(i) = 1
es la única expresión de asignación. Hay dos subexpresiones (un identificador entre paréntesis(i)
y una constante numérica1
).fuente
Esta respuesta está inspirada en @Eric Postpischil.
la producción de a
assignment-expression
es:en el estándar, las
assignment expression
expresiones de medios específicos con operadores de asignación. Entonces:entonces la regla:
solo se ajusta a la producción
<unary-expression> <assignment-operator> <assignment-expression>
, no a<conditional-expression>
en el ejemplo
(i) =1
,i
es un<assignment-expression>
pero no unassignment expression
, es un,<conditional-expression>
así que es un valor, así(i)
es un valor.fuente