Redefinición de un puntero en ámbito global.

En esta pregunta estoy completamente confundido acerca de este aspecto aparentemente básico de C. Considere estas dos líneas de código:

int *ptr; *ptr = 2; 

gcc emitirá las siguientes advertencias:

 main.cpp:4:1: warning: data definition has no type or storage class [enabled by default] *ptr = 2; ^ main.cpp:4:2: warning: type defaults to 'int' in declaration of 'ptr' [enabled by default] *ptr = 2; ^ main.cpp:4:8: warning: initialization makes pointer from integer without a cast [enabled by default] *ptr = 2; ^ 

¿Qué tipo de ptr predeterminado es ptr , int o int* (como en, es ptr un puntero o un int )? Si es así, ¿significa esto que ptr está apuntando a la dirección 2, o eso no ha cambiado? Supongo que ha cambiado porque se bloquea a menos que le dé a ptr una dirección válida.

 int i = 5; int *ptr; *ptr = &i; int main(){ printf("%d", *ptr); // 5 } 

Soy consciente de la posibilidad de un comportamiento indefinido y de que no debe ignorar las advertencias, pero estoy tratando de ver qué sucede realmente aquí.

Para el contexto, vea la cadena de comentarios debajo de esta respuesta .

Esto es lo que está sucediendo: dado que las dos líneas que está mostrando están en el scope del archivo (a diferencia del scope local), ambas líneas se tratan como declaraciones , no como una statement y una statement de asignación. Esto se debe a que podría no haber declaraciones en el ámbito del archivo, solo se permiten declaraciones y definiciones.

Las antiguas reglas C permitían declaraciones de tipo int para omitir el tipo por completo. Por lo tanto, la segunda línea es

  • Una statement / definición de ptr
  • … que es un puntero, porque tiene un asterisco
  • … y también es un puntero a int , porque falta el tipo.

La última regla es muy arcaica y ha quedado en desuso en la versión ANSI del estándar de idioma. Por eso recibes una advertencia. Si cambias tu código a

 int *ptr; int *ptr = &i; 

Su código se va a comstackr y ejecutar ( demo ).

Ahora queda una pregunta: ¿por qué el comstackdor no se queja de las declaraciones duplicadas? Resulta que el comstackdor tratará varias declaraciones idénticas como una sola, siempre y cuando sean completamente idénticas entre sí.