2011-06-16 19 views
24

Por ejemplo:C & C++ predeterminado vinculación variable global, múltiples declaración y definición del problema

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 

¿Existe alguna diferencia de vinculación variable global entre C & C++?

+7

1 se les pide amablemente – Stuti

+3

Puede evitar el problema en C++ utilizando cualquiera 'static' o (preferiblemente) un espacio de nombres sin nombre, pero ese no es su pregunta. No estoy lo suficientemente familiarizado con las reglas de vinculación C (a diferencia de C++) para responder eso, me temo. – Sven

+2

http://blogs.oracle.com/ali/entry/what_are_tentative_symbols –

Respuesta

18

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 vinculación externa en C, pero solo una definición en todas las unidades de traducción en un programa.

Es una extensión comúnmente implementada para permitir definiciones tentativas en 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 un concepto tentativo, y sigue siendo ilegal tener múltiples definiciones de un objeto en las unidades de traducción de un programa.

Para el caso C, es posible que desee consultar this question.

+0

Gracias por una muy buena respuesta, soy muy apreciado :) – Bossliaw

4

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

+0

Gracias por su respuesta, Soy muy apreciado – Bossliaw

+0

@Artefacto: +1 por mencionar esto – legends2k

2

Existen tres formas para la resolución del problema:

  1. Si la variable a es la misma en ambos archivos, debe declarar como extern en todos los archivos excepto uno. La palabra clave extern indica al vinculador 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 el que se declara.

  3. O puede usar el espacio de nombre sin nombre.

+0

Gracias por su respuesta, soy muy apreciado – Bossliaw

+0

También hay '-zmuldefs', pero en general se considera una solución malvada –

1

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

Uso extern para evitar

+0

Gracias por su respuesta, soy muy apreciado – Bossliaw

Cuestiones relacionadas