Struct avec une valeur dans un fichier d’en-tête provoquant une erreur de l’éditeur de liens «symbole en double»

Ceci est un exemple réduit d’un projet beaucoup plus vaste. Vous pouvez le voir ici .

J’ai un fichier d’en-tête contenant les limites des fonctions de l’heure système. Appelez-le time_config.h.

#ifndef TIME_CONFIG_H #define TIME_CONFIG_H #define HAS_TIMEGM #define SYSTEM_LOCALTIME_MAX 2147483647 #define SYSTEM_LOCALTIME_MIN -2147483648 #define SYSTEM_GMTIME_MAX 2147483647 #define SYSTEM_GMTIME_MIN -2147483648 const struct tm SYSTEM_MKTIME_MAX = { 7, 14, 19, 18, 0, 138, 0, 0, 0, 0, 0 }; const struct tm SYSTEM_MKTIME_MIN = { 52, 45, 12, 13, 11, 1, 0, 0, 0, 0, 0 }; #endif 

Ensuite, il y a un fichier d’en-tête définissant mes fonctions temporelles. Appelez ça mytime.h. Il comprend time_config.h.

 #ifndef MYTIME_H #define MYTIME_H #include "time_config.h" #ifndef HAS_TIMEGM time_t timegm(const struct tm*); #endif #endif 

Il existe mytime.c qui inclut mytime.h et définit timegm (), si nécessaire.

Je le comstack dans un fichier object …

 gcc  -I. -c -o mytime.o mytime.c 

Et liez-le dans un test binary, t / year_limit.tc inclut également mytime.h.

 gcc  -I. mytime.ot/year_limit.tc -ot/year_limit.t 

Quelles erreurs avec:

 ld: duplicate symbol _SYSTEM_MKTIME_MAX in /var/folders/eJ/eJzTVP7oG7GVsKYHJtMprE+++TI/-Tmp-//ccMe5DXb.o and mytime.o collect2: ld returned 1 exit status 

Étant donné que time_config.h est généré au cours du processus de construction par une parsing du système, il serait très pratique de conserver toutes les valeurs ensemble dans un seul fichier d’en-tête, voire plusieurs fichiers d’en-tête. La modification du fichier .c au cours du processus de génération est plus difficile.

Cela fonctionne bien sans les structures. Comment déclarer les structures de date min / max dans un fichier d’en-tête sans provoquer ce conflit? Ou est-ce que je comstack et relie mal?

PS Ceci est ANSI C89.

 const struct tm SYSTEM_MKTIME_MAX = { 7, 14, 19, 18, 0, 138, 0, 0, 0, 0, 0 }; 

Ce qui précède déclare et définit l’object SYSTEM_MKTIME_MAX ; Plusieurs inclusions de l’en-tête mènent à plusieurs définitions.

Mettez un extern dans l’en-tête et placez la définition dans le fichier d’implémentation.

Dans votre en-tête (.h) vous avez besoin de:

 extern const struct tm SYSTEM_MKTIME_MAX; extern const struct tm SYSTEM_MKTIME_MIN; 

Dans votre implémentation (.c) vous avez besoin de:

 const struct tm SYSTEM_MKTIME_MAX = { 7, 14, 19, 18, 0, 138, 0, 0, 0, 0, 0 }; const struct tm SYSTEM_MKTIME_MIN = { 52, 45, 12, 13, 11, 1, 0, 0, 0, 0, 0 }; 

En C, les constantes ont un lien externe et doivent donc être définies dans des fichiers .c.

En C ++, ils ont un lien interne et pourraient donc être définis dans l’en-tête.

L’en-tête ne doit contenir que la déclaration. Alors changez l’en-tête en:

 extern const struct tm SYSTEM_MKTIME_MAX; 

Et en cpp faire une affectation

 const struct tm SYSTEM_MKTIME_MAX = {...