Sección §6.5.3.2 "Dirección y indirección operadores" ¶3 dice (sección relevante solamente):C estándar frente a la simplificación inconsistencia
El & operador unitario devuelve la dirección de su operando. ... Si el operando es el resultado de un operador único
*
, ni ese operador ni el operador&
se evalúan y el resultado es como si ambos se hubieran omitido, excepto que las restricciones sobre los operadores aún se aplican y el resultado no es lvalue Del mismo modo, si el operando es el resultado de un operador de[]
, ni el operador&
ni el unario*
que está implícito en la[]
se evalúa y el resultado es como si el operador&
se retiraron y el operador[]
se cambiaron a un operador+
. ...
Esto significa que este:
#define NUM 10
int tmp[NUM];
int *i = tmp;
printf("%ti\n", (ptrdiff_t) (&*i - i));
printf("%ti\n", (ptrdiff_t) (&i[NUM] - i));
Debe ser perfectamente legal, la impresión de 0 y el NUM
(10). El estándar parece muy claro que ambos casos deben ser optimizados.
Sin embargo, no parece requerir la siguiente ser optimizado:
struct { int a; short b; } tmp, *s = tmp;
printf("%ti\n", (ptrdiff_t) (&s->b - s));
Esto parece muy inconsistente. No veo ninguna razón para que el código anterior no imprima el sizeof(int)
más (improbable) relleno (posiblemente 4).
Simplificar una expresión &->
va a ser el mismo conceptualmente (en mi humilde opinión) como &[]
, una simple dirección-más-desplazamiento. Incluso es un desplazamiento que se podrá determinar en tiempo de compilación, en lugar de potencialmente en tiempo de ejecución con el operador []
.
¿Hay algo en el fundamento acerca de por qué esto es aparentemente inconsistente?
He visto muchísimas preguntas sobre los estándares de C y C++ en las que no sabía cómo hacer otra cosa que votar, favoritos y esperar para leer las respuestas. Se siente raro haber escrito uno. –
interesante ... ¡MSVC++ imprime 4! – Abhi
@Abhi Rao - GCC (4.0) con -Wall -Wextra -Werror compila e imprime 4 sin ninguna queja. –