2010-08-15 14 views
5

Estoy tratando de compartir la misma variable entre dos archivos .cpp, incluyen el mismo archivo .h.problemas con la variable global compartida entre los archivos de origen (estoy usando incluir guardias)

Pero recibo errores de enlace, diciéndome que tengo múltiples definiciones. Que me parece extraño, ya que estoy usando incluir guardias

//main.cpp 
#include <cstdio> 
#include "shared.h" 

int main(){ 
    shared_int = 5; 
    printVal(); 
    return 0; 
} 


//shared.h 
#ifndef INCLUDE_GUARD_H 
#define INCLUDE_GUARD_H 
#include <cstdio> 
#include <cstdlib> 
int shared_int; 
int printVal(); 
#endif 

//shared.cpp 
#include <cstdio> 
#include "shared.h" 


int printVal(){ 
    fprintf(stderr,"a: %d\n",shared_int); 
    return 0; 
} 

estoy comping como

g++ shared.cpp -c;g++ main.cpp shared.o 
shared.o:(.bss+0x0): multiple definition of `shared_int' 
/tmp/cci8w8Am.o:(.bss+0x0): first defined here 
collect2: ld returned 1 exit status 

gracias

Actualización: El todavía no funciona 'externo', pero ahora obtener una referencia indefinida Estos son los archivos actualizados

//shared.h 
#ifndef INCLUDE_GUARD_H 
#define INCLUDE_GUARD_H 
#include <cstdio> 
#include <cstdlib> 
//extern "C" int shared_int;//i've tried both 
extern int shared_int; 
int printVal(); 
#endif 

//shared.cpp 
#include <cstdio> 
#include "shared.h" 

int printVal(){ 
    fprintf(stderr,"a: %d\n",shared_int); 
    return 0; 
} 

//main.cpp 
#include <cstdio> 
#include "shared.h" 

int main(){ 
    int shared_int = 5; 
    printVal(); 
    return 0; 
} 

Esta es la forma en Compilo

g++ main.cpp shared.o 
shared.o: In function `printVal()': 
shared.cpp:(.text+0x6): undefined reference to `shared_int' 
collect2: ld returned 1 exit status 
+1

La respuesta ya está dada por Greg, pero asegúrese de entender la diferencia entre una declaración y una definición. Es una distinción importante que lo ayudará a comprender mejor los mensajes del compilador y la semántica general del código. – Nick

+0

Su código actualizado agrega 'extern" C "' (que es algo bastante diferente de lo que sugerí en mi respuesta), y no introduce ninguna definición. Prueba lo que sugerí en mi respuesta. –

+0

@greg Hewgill. Lo he intentado también, el mismo error de enlace.Gracias – monkeyking

Respuesta

15

La declaración en su archivo de cabecera necesita un extern:

extern int shared_int; 

A continuación, tendrá una instancia real de la definición de un archivo C++ (como en shared.cpp):

int shared_int; 

El incluyen guardias que está usando aquí están las buenas prácticas, pero no tendrá ningún efecto en esta situación. El protector de inclusión evita que el archivo de encabezado se incluya más de una vez en el mismo archivo de origen . Tal situación normalmente no ocurre a menos que tenga archivos de encabezado incluidos indirectamente desde otros archivos de encabezado.

+0

+1 Greg. También noté que @monkeyking está mezclando los archivos de encabezado C .h con el compilador C++. Esa no es una práctica muy buena, así que simplemente señalaré que probablemente sea mejor si fuerza el símbolo a exportar como un símbolo C para evitar problemas de manipulación de nombres. Simplemente defina la variable en shared.h como: extern "C" int shared_int; – karlphillip

+3

@karlphillip: No existe un "archivo de encabezado C": los archivos de encabezado se compilan con el compilador #includes. El nombre '.h' es perfectamente aceptable para C++. Algunas personas pueden usar '.hpp' o' .hxx', pero eso es solo estilo y no tiene ningún significado. –

0

En primer lugar, los globales no son una buena idea y hay que evitarlos todo lo posible. Asumiendo que en su situación particular, se requiere obligatoriamente por cualquier razón, desde una perspectiva de OO puro, me acercaría de la siguiente manera:

a) Defina la variable global en un archivo, por ejemplo, a.cpp (también si variable puede ser embebido en un espacio de nombres)

b) Escribir obtener funciones/set en a.cpp

c) el acceso a la variable global en a.cpp utilizando las funciones get/set.

De esta manera, tendría un diseño muy modular con una interfaz bien definida.

-1

eres muy pronto:

//shared.h 
#ifndef INCLUDE_GUARD_H 
#define INCLUDE_GUARD_H 
#include <cstdio> 
#include <cstdlib> 
//extern "C" int shared_int;//i've tried both 
extern int shared_int; 
int printVal(); 
#endif 

//shared.cpp 
#include <cstdio> 
#include "shared.h" 

int printVal(){ 
    fprintf(stderr,"a: %d\n",shared_int); 
    return 0; 
} 

//main.cpp 
#include <cstdio> 
#include "shared.h" 

int shared_int = 0; // definition (extern ... is declaration) 
        // initialize force definition 

int main(){ 
    shared_int = 5; 
    printVal(); 
    return 0; 

}

Cuestiones relacionadas