Redeclaración de variable global vs variable local

5 minutos de lectura

avatar de usuario
Jeegar Patel

Cuando compilo el siguiente código

#include<stdio.h>

int main()
{
  int a;
  int a = 10;
  printf("a is %d \n",a);
  return 0;
}

me sale un error:

test3.c: In function ‘main’:
test3.c:6:5: error: redeclaration of ‘a’ with no linkage
test3.c:5:5: note: previous declaration of ‘a’ was here

Pero si hago que la variable sea global, entonces funciona bien.

#include<stdio.h>

int a;
int a = 10;
int main()
{
  printf("a is %d \n",a);
  return 0;
}

¿Por qué declarar la misma variable global dos veces no es un error, pero hacerlo para una variable local es un error?

  • En la última parte de la respuesta de esta pregunta.

    – MoeCake

    22 de enero de 2014 a las 6:50


  • @downvoters se preocupan por comentar por una razón. Si vota negativamente por duplicar, vote por cerrar y no vote negativamente.

    – Jeegar Patel

    22 de enero de 2014 a las 8:23

En C, el enunciado int a; cuando se hace en el ámbito del archivo, es una declaración y un definición tentativa. Puede tener tantas definiciones tentativas como desee, siempre que coincidan entre sí.

Si aparece una definición (con un inicializador) antes del final de la unidad de traducción, la variable se inicializará con ese valor. Tener múltiples valores de inicialización es un error del compilador.

Si se llega al final de la unidad de traducción y no se encuentra una definición no tentativa, la variable se inicializará en cero.

Lo anterior no aplica para variables locales. Aquí una declaración también sirve como definición, y tener más de una conduce a un error.

  • En el caso de una variable local, dado que la declaración y la definición son las mismas, ¿por qué obtenemos un error de redeclaración y por qué no un error de redefinición? En el caso de una variable local, en realidad estamos definiendo y, por lo tanto, el error debería haber sido una redefinición, ¿verdad?

    – Rajesh

    15 de junio de 2017 a las 6:06

  • Ver C11, 6.9.2 Definiciones de objetos externos

    –Paul Ogilvie

    24 de diciembre de 2017 a las 16:01

  • Si bien es correcto, realmente no responde la pregunta. La verdadera razón es que solo se le permite tener una declaración de un nombre en más alcances La excepción es el alcance del archivo: puede tener cualquier cantidad de declaraciones para un nombre en el alcance del archivo siempre que sean compatibles. Esto es independiente de cualquier definición.

    – Chris Dodd

    26 de diciembre de 2017 a las 2:46


La otra razón en la que podría pensar es que las variables globales no inicializadas se almacenan en el BSS (segmento estructurado de bloque), donde las variables globales que se inicializan se almacenan en el segmento de datos.

Supongo que hay algún tipo de resolución de espacio de nombres y cuando hay un conflicto, la variable en el segmento de datos anula la del segmento estructurado de bloque.

si fueras a declarar

int a = 5 int a = 10

en el alcance global (ambos en el segmento de datos) habría conflicto como se esperaba.

  • De acuerdo con su explicación, debe haber dos copias de auno en los segmentos bss y data (que son detalles de implementación de todos modos, nunca mencionados en el estándar).

    – Pretoriano

    22 de enero de 2014 a las 7:32

avatar de usuario
vaibhav jainista

No puede tener dos variables globales con el mismo nombre en el programa C. C podría permitir múltiples definiciones en el mismo ámbito de archivo a través de la regla de definición tentativa, pero en cualquier caso, todas las definiciones se referirán a la misma variable.

Variable local

En C, múltiples variables locales no se “fusionan” en una sola.

Todas las variables locales con el mismo nombre se referirán a la pieza de memoria de diferente tamaño int.

 #include<stdio.h>

 int main()
 {
  int a;
  int a = 10;
  printf("a is %d \n",a);  
  return 0;
 }

Entonces al asignar la memoria a la redeclaración de la misma variable da Error.

Variable global

En C, múltiples variables globales se “fusionan” en una sola. Entonces, de hecho, solo tiene una variable global, declarada varias veces. Esto se remonta a una época en la que no se necesitaba extern (o posiblemente no existía, no estoy seguro) en C.

En otras palabras, todas las variables globales con el mismo nombre se convertirán en una sola variable, por lo que su

#include<stdio.h>

int a;
int a = 10;
int main()
{
printf("a is %d \n",a);
return 0;
}

se referirá a la misma pieza de memoria de tamaño int.

  • Si las declaraciones son int a=5;int a=10; a nivel global, ¿cuál será el valor final? ¡Resulta que es un error de compilación!

    – nitish712

    22 de enero de 2014 a las 6:58

  • @Vaibhav cualquier especificación para su concepto “fusionado”. Escuché sobre esta primera vez.!

    – Jeegar Patel

    22 de enero de 2014 a las 7:00

  • @ nitish712 puede tener múltiples declaraciones pero solo 1 definición.

    – teseracto

    22 de enero de 2014 a las 7:08

  • @VaibhavJain Entonces, para mi pregunta, ¿por qué me da un error de compilación? Tal vez deberías decir declaration en lugar de definition como señaló @tesseract. Mira esto

    – nitish712

    22 de enero de 2014 a las 7:14

  • Las dos primeras oraciones en su respuesta (extrañamente formateadas como código) son engañosas. Usted dice que se permiten múltiples definiciones, y eso no es cierto. Suponiendo que la variable tiene un vínculo externo, no se permiten múltiples definiciones en varias unidades de traducción, y mucho menos en la misma. Ahora, múltiples tentativo las definiciones están permitidas en la misma unidad de traducción (y en varias en la mayoría de los compiladores), pero al explicar la diferencia entre definiciones tentativas y no tentativas, realmente necesita ser explícito de cuál está hablando.

    – Pretoriano

    22 de enero de 2014 a las 7:23

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad