Tengo una pregunta sobre la palabra clave register en C.

Encontré que el nombre de la matriz register (por ejemplo, array) se puede asignar a la variable de puntero, mientras que &array[0] no.

¿Puede explicar por qué se puede asignar un nombre de matriz a un puntero? O, si alguien ya lo explicó, avíseme los enlaces para que pueda echar un vistazo y obtener la respuesta. Gracias.

Esto es lo que probé:

Leí cppreference que explica la palabra clave register y dice:

las matrices de registros no se pueden convertir en punteros.

Además, leí el borrador C89 que dice:

La implementación puede tratar cualquier declaración de registro simplemente como una autodeclaración. Sin embargo, ya sea que se utilice realmente almacenamiento direccionable o no, la dirección de cualquier parte de un objeto declarado con el registro de especificador de clase de almacenamiento no se puede calcular , ya sea explícitamente (mediante el uso del operador unario & como se discutió en 3.3.3.2) o implícitamente (convirtiendo un nombre de matriz en un puntero como se discutió en 3.2.2.1). Por lo tanto, el único operador que se puede aplicar a una matriz declarada con un registro especificador de clase de almacenamiento es tamaño de.

Parece que no puedo asignar el nombre de la matriz de registro al puntero para obtener su dirección.

Además, para encontrar la respuesta, busqué aquí y encontré esta pregunta: Dirección de la variable de registro. Hay buenas respuestas, sin embargo, todavía no pude encontrar la respuesta que quería.

Aquí está el código que probé. Compilé este código a través de Clang con la bandera -std=c89:

register int array[10];
int* p;

p = array;     // Compiled without warning or error
p = &array[0]; // Compiled with error which I expected

Esperaba que tanto p = array; como p = &array[0]; causaran un error de compilación, pero solo p = &array[0]; cometió un error de compilación.

3
MMX 25 sep. 2019 a las 04:05

1 respuesta

La mejor respuesta

Este es un error en el compilador de Clang. GCC muestra un error en ambas líneas.

Al discutir la conversión automática de "matriz de tipo " a "puntero a tipo ", C 2018 6.3.2.1 dice:

… Si el objeto de matriz tiene una clase de almacenamiento de registros, el comportamiento no está definido.

Además, la nota 124 al pie de C 2018 dice:

... la dirección de cualquier parte de un objeto declarado con el especificador de clase de almacenamiento register no se puede calcular, ni explícitamente (mediante el uso del operador unario & como se discutió en 6.5.3.2) o implícitamente (convirtiendo un nombre de matriz a un puntero como se discutió en 6.3.2.1) ...

Obviamente, p = array; convierte array en un puntero, como se discutió en 6.3.2.1, pero esta nota al pie (que no es normativa pero nos dice la intención en este caso de manera bastante explícita) dice el valor de ese puntero no se puede calcular.

Dado que el comportamiento no está definido por el estándar C, una implementación de C podría definirlo como una extensión. Sin embargo, el comportamiento inconsistente entre array y &array[0] sugiere que esto no es una extensión deliberada de Clang sino que es un error.

3
Eric Postpischil 25 sep. 2019 a las 01:32