Hmm, sospecho que esto es algo que no habría funcionado en los primeros días de C. Sin embargo, es inteligente.
Tomando los pasos uno a la vez:
&a
obtiene un puntero a un objeto de tipo int [5]
+1
obtiene el siguiente objeto suponiendo que hay una serie de esos
*
convierte efectivamente esa dirección en puntero de tipo a int
-a
resta los dos punteros int, devolviendo el recuento de instancias int entre ellos.
No estoy seguro de que sea completamente legal (en esto me refiero a un abogado de idiomas legal, no funcionará en la práctica), dadas algunas de las operaciones de tipo que están sucediendo. Por ejemplo, solo está "permitido" restar dos punteros cuando apuntan a elementos en la misma matriz. *(&a+1)
se sintetizó accediendo a otra matriz, aunque sea una matriz principal, por lo que en realidad no es un puntero en la misma matriz que a
. Además, aunque puede sintetizar un puntero más allá del último elemento de una matriz, y puede tratar cualquier objeto como una matriz de 1 elemento, la operación de desreferenciar ( *
) no está "permitida" en este puntero sintetizado, aunque no tiene comportamiento en este caso!
Sospecho que en los primeros días de C (sintaxis K&R, ¿alguien?), Una matriz se descompuso en un puntero mucho más rápido, por lo que *(&a+1)
podría devolver la dirección del siguiente puntero de tipo int **. Las definiciones más rigurosas de C ++ moderno definitivamente permiten que el puntero al tipo de matriz exista y conozca el tamaño de la matriz, y probablemente los estándares de C han seguido su ejemplo. Todo el código de función C solo toma punteros como argumentos, por lo que la diferencia técnica visible es mínima. Pero solo estoy adivinando aquí.
Este tipo de pregunta de legalidad detallada generalmente se aplica a un intérprete de C, o una herramienta de tipo pelusa, en lugar del código compilado. Un intérprete podría implementar una matriz 2D como una matriz de punteros a matrices, porque hay una característica de tiempo de ejecución menos para implementar, en cuyo caso desreferenciar el +1 sería fatal, e incluso si funcionara, daría la respuesta incorrecta.
Otra posible debilidad puede ser que el compilador de C pueda alinear la matriz externa. Imagine si se tratara de una matriz de 5 caracteres ( char arr[5]
), cuando el programa lo realiza &a+1
invoca el comportamiento de "matriz de matriz". El compilador podría decidir que una matriz de matriz de 5 caracteres ( char arr[][5]
) se genera realmente como una matriz de matriz de 8 caracteres ( char arr[][8]
), de modo que la matriz externa se alinea muy bien. El código que estamos discutiendo ahora informaría que el tamaño de la matriz es 8, no 5. No estoy diciendo que un compilador particular definitivamente haga esto, pero podría.
&a + 1
no apunta a ningún objeto válido, por lo que no es válido.