web-dev-qa-db-fra.com

Définition multiple du premier défini ici gcc

J'ai ces fichiers

consumer.cpp
consumer.hpp
defines.hpp
main.cpp
makefile
producer.cpp
producer.hpp

voici le fichier define.hpp

#ifndef DEFINES_HPP
#define DEFINES_HPP

#include <cassert>
#include <pthread.h> 
#include <queue>
#include <stdlib.h>
#include <string>
#include <unistd.h>

pthread_mutex_t set_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var = PTHREAD_COND_INITIALIZER;

std::queue<int> q;

#endif // DEFINES_HPP

Ce fichier define.hpp est inclus dans le fichier manufacturer.hpp et consumer.hpp. les fichiers producteur.hpp et consommateur.hpp inclus respectivement dans producteur.cpp et consommateur.cpp et encore dans main.cpp. Lors de la compilation, j'obtiens une erreur.

g++ -o main producer.cpp consumer.cpp main.cpp producer.hpp consumer.hpp defines.hpp -lpthread -ggdb
/tmp/ccctuRp7.o: In function `__gnu_cxx::new_allocator<int>::destroy(int*)':
/home/vardan/test/consumer.cpp:8: multiple definition of `set_queue_mutex'
/tmp/cciGccft.o:/home/vardan/test/producer.cpp:8: first defined here
/tmp/ccctuRp7.o: In function `std::deque<int, std::allocator<int> >::front()':
/home/vardan/test/consumer.cpp:12: multiple definition of `condition_var'
/tmp/cciGccft.o:/home/vardan/test/producer.cpp:11: first defined here
/tmp/ccctuRp7.o: In function `global::consumer::entry_point(void*)':
/home/vardan/test/consumer.cpp:17: multiple definition of `q'
/tmp/cciGccft.o:/home/vardan/test/producer.cpp:17: first defined here
/tmp/ccKCxptM.o: In function `main':
/home/vardan/test/main.cpp:8: multiple definition of `set_queue_mutex'
/tmp/cciGccft.o:/home/vardan/test/producer.cpp:8: first defined here
/tmp/ccKCxptM.o: In function `main':
/home/vardan/test/main.cpp:13: multiple definition of `condition_var'
/tmp/cciGccft.o:/home/vardan/test/producer.cpp:11: first defined here
/tmp/ccKCxptM.o: In function `main':
/home/vardan/test/main.cpp:25: multiple definition of `q'
/tmp/cciGccft.o:/home/vardan/test/producer.cpp:17: first defined here
collect2: error: ld returned 1 exit status
make: *** [main] Error 1

Voici mon makefile

main : producer.cpp consumer.cpp main.cpp producer.hpp consumer.hpp defines.hpp
    g++ -o $@ $^ -lpthread -ggdb
.PHONY : clean
clean:
    rm -rf main *.swf *.o

Comment résoudre ce problème ?

17
user1886376

En C++ (ainsi qu'en C) il y a une différence entre déclarer et définir des choses comme les variables. Ce que vous faites dans le fichier d'en-tête est définition les variables, ce qui signifie que chaque fichier source qui inclut le fichier d'en-tête aura les définitions.

Dans le fichier d'en-tête, vous devez uniquement déclarer les variables, puis dans un seul fichier source les définir.

Donc, dans le fichier d'en-tête, faites par exemple.

extern pthread_mutex_t set_queue_mutex;
extern pthread_cond_t  condition_var;

extern std::queue<int> q;

Et puis dans un seul fichier source mettez les définitions (ce que vous avez maintenant).

34