c & c++ problema predeterminado de vinculación de variables globales, declaración múltiple y definición


Por ejemplo:

Code1.c/.cpp

int a;

// ... and so on

Code2.c/.cpp

int a;

int main(void) {
    return 0;
}

Ir a compilar:

$gcc code1.c code2.c      # this is fine
$

$g++ code1.cpp code2.cpp  # this is dead
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a'
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

¿Hay alguna diferencia de enlace variable global entre C y C++?

Author: Bossliaw, 2011-06-16

4 answers

No es estrictamente legal. int a; es una definición tentativa en C. Se le permiten múltiples definiciones tentativas y como máximo una definición no tentativa por unidad de traducción de cada objeto con enlace externo en C, pero solo una definición a través de todas las unidades de traducción en un programa.

Es una extensión comúnmente implementada para permitir definiciones tentativas a través de múltiples unidades de traducción en C siempre que no más de una unidad de traducción contenga una definición no tentativa, pero no es estrictamente estándar.

En C++ int a; es solo una definición - no hay concepto de tentativa - y sigue siendo ilegal tener múltiples definiciones de un objeto a través de las unidades de traducción de un programa.

Para el caso C, puede que desee mirar esta pregunta.

 19
Author: CB Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:01:00

Es ilegal en ambos, pero los compiladores de C generalmente implementan una extensión. Ver esta respuesta.

 4
Author: Artefacto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:22:56

Hay tres maneras de resolver el problema:

  1. Si la variable a es la misma en ambos archivos, debe declararla como extern en todos los archivos excepto uno. extern la palabra clave le dice al enlazador que este nombre se encuentra en otros archivos.

  2. Puede usar la palabra clave static para limitar el alcance de la variable a un archivo. En la que se declara.

  3. O puede usar un espacio de nombres sin nombre.

 2
Author: George Gaál,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-16 11:38:14

El compilador G++ es más estricto que el compilador gcc. También depende de la versión de gcc, puede ser una versión superior de gcc, es decir, 4.X en adelante puede dar el mismo error.

Use extern para evitar

 1
Author: Stuti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-16 11:40:47