Lanzar un puntero no produce un valor l. ¿Por qué?
Después de publicar aquí una de mis respuestas más controvertidas , me atrevo a hacer algunas preguntas y eventualmente llenar algunos vacíos en mi conocimiento.
¿Por qué una expresión de este tipo no se ((type_t *) x)
considera un valor l válido, suponiendo que x
en sí misma es un puntero y un valor l, no solo una expresión?
Sé que muchos dirán "la norma no lo permite", pero desde un punto de vista lógico parece razonable. ¿Cuál es la razón por la que la norma no lo permite? Después de todo, dos punteros cualesquiera son del mismo tamaño y el tipo de puntero es solo una abstracción en tiempo de compilación que indica el desplazamiento apropiado que se debe aplicar al realizar aritmética de punteros.
Un ejemplo aún mejor, unario +
produce un valor r, al igual que x+0
.
La razón subyacente es que todas estas cosas, incluido tu elenco, crean un nuevo valor. Al convertir un valor al tipo que ya es, también se crea un nuevo valor, sin importar si los punteros a diferentes tipos tienen la misma representación o no. En algunos casos, el nuevo valor resulta ser igual al valor anterior, pero en principio es un valor nuevo, no está destinado a usarse como referencia al objeto anterior y por eso es un valor r.
Para que estos sean valores l, el estándar tendría que agregar algunos casos especiales en los que ciertas operaciones cuando se usan en un valor l dan como resultado una referencia al objeto antiguo, en lugar de un valor nuevo. AFAIK no hay una gran demanda para esos casos especiales.
El resultado de una conversión nunca es un valor en sí mismo. Pero *((type_t *) x)
es un valor l.
Porque las expresiones convertidas en general no producen valores l.