es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué es una declaración externa implícita inválida si hay una declaración estática previa?

Considere el siguiente programa de ejemplo:


#include <stdio.h> static int n = 123; extern int n; int main(void){ printf("n is %d\n",n); return 0; }

Se compila correctamente con gcc -std=c99 -pedantic myprog.c. La variable n tiene un enlace estático según C99 § 6.2.2 Linkages of identifiers, parte 4:

Para un identificador declarado con el especificador de clase de almacenamiento extern en un ámbito en el que una declaración previa de ese identificador es visible, si la declaración previa especifica un enlace interno o externo, el enlace del identificador en la declaración posterior es el mismo que el enlace especificado en la declaración previa. Si no hay declaración anterior visible, o si la declaración anterior no especifica enlace, entonces el identificador tiene un enlace externo.

Ahora elimina extern:


#include <stdio.h> static int n = 123; int n; int main(void){ printf("n is %d\n",n); return 0; }

Este programa no se compila. GCC da este error:

myprog.c:4:5: error: non-static declaration of 'n' follows static declaration
    4 | int n;
      |     ^
myprog.c:3:12: note: previous definition of 'n' was here
    3 | static int n = 123;
      |

¿Por qué ocurre este error? Pensaba que int n; en el segundo programa debería ser equivalente a extern int n;. Del estándar C99, § 6.2.2 Linkages of identifiers, parte 5:

Si la declaración de un identificador para un objeto tiene un ámbito de archivo y ningún especificador de clase de almacenamiento, su enlace es externo.</stdio.h></stdio.h>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El error ocurre porque la primera declaración de n tiene un enlace estático, lo que significa que solo se puede acceder dentro de la misma unidad de traducción (es decir, el mismo archivo fuente en este caso). Cuando eliminamos la palabra clave “extern” en el segundo programa, creamos una nueva definición de n con enlace externo, lo que significa que puede ser accedido por otras unidades de traducción.

    Dado que la primera declaración de n tiene enlace estático, no puede ser seguida por una declaración con enlace externo. Esto viola el estándar C99, que dice que si una declaración previa especifica enlace interno o externo, el enlace del identificador en la declaración posterior debe ser el mismo que el enlace especificado en la declaración previa. Por lo tanto, el segundo programa no se compila y produce el mensaje de error mostrado.

Comments are closed.