En C, ¿por qué las declaraciones múltiples funcionan bien para una variable global pero no para una variable local?

En el siguiente código, ¿por qué las declaraciones múltiples (y una definición) funcionan bien para una variable global x pero no para una variable local y que está dentro de la función main() ? Muestra los siguientes 2 errores:

1) restatement de ‘y’ sin vinculación

2) la statement anterior de ‘y’ estaba aquí

¿Por qué muestra un error para la variable local pero no para la variable global? No solo mi libro, pero los siguientes 2 enlaces de este foro indican claramente que podemos declarar una variable varias veces (aunque solo una vez).

link1 link2

Y tenga la amabilidad de explicar qué significa la parte “sin enlace” del primer error “restatement de ‘y’ sin vinculación”. ¿Qué vínculo y a quién? ¿Dónde se vincularía una variable local?

  #include int x; int x; int x=303; int main(void) { int y; int y; int y=776; //Works fine if above 2 declarations are removed!! printf("The value of x is %d,and of y is %d",x,y); } 

En C y C ++, int y; dentro de una función es a la vez una statement y una definición.

En C, int x; en el scope del archivo (fuera de cualquier función) hay una statement y una definición tentativa . Se permiten múltiples definiciones tentativas; solo se permite una definición .

Esta es la manera definida en el estándar C99, sección 6.2.2, parte 2:

En el conjunto de unidades de traducción y bibliotecas que constituyen un progtwig completo, cada statement de un identificador particular con un enlace externo denota el mismo objeto o función. Dentro de una unidad de traducción, cada statement de un identificador con enlace interno denota el mismo objeto o función. Cada statement de un identificador sin vinculación denota una entidad única.

Las variables “globales” x tienen un enlace externo, por lo que denotan el mismo objeto. Las variables locales y , por otro lado, no tienen ningún vínculo, por lo que hay una colisión.

Referencias: C99 Standard .

Con las variables externas, cualquier statement que no sea una inicialización es una definición tentativa. Estos por sí mismos no crean ningún almacenamiento, por lo que se permiten múltiples. Entonces tomando su ejemplo:

 int x; // tentative def int x; // and again -- ok int x=303; // definition -- ok int x=303; // multiple definition -- error 

Si al final del archivo solo ha habido definiciones tentativas, la variable se define una vez y se establece en 0.

Esto significa que si enlaza a otro archivo que también tiene una definición tentativa de x , tendrá un error de acuerdo con el estándar. La mayoría de los comstackdores / vinculadores siempre han permitido esto, sin embargo, y está definido en el estándar como una extensión.

Con las variables locales, cada statement es una definición debido a las reglas de scope. Esto, sin embargo, está permitido:

 void func(void) { int y = 0; { int y = 1; // a completely different y } }