2010-02-05 22 views
2

這是一個大得多的項目的簡化示例。你可以看到它here帶有「重複符號」鏈接器錯誤的頭文件中的值的結構

我有一個頭文件包含系統時間函數的限制。將其稱爲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 

然後有一個頭文件定義我的時間函數。稱之爲mytime.h。它包含time_config.h。

#ifndef MYTIME_H 
#define MYTIME_H 

#include "time_config.h" 

#ifndef HAS_TIMEGM 
time_t timegm(const struct tm*); 
#endif 

#endif 

還有mytime.c,其中包含mytime.h並在必要時定義timegm()。

我把它編譯成目標文件...

gcc <a lot of warning flags> -I. -c -o mytime.o mytime.c 

並鏈接到測試二進制,T/year_limit.t.c還包括mytime.h。

gcc <a lot of warning flags> -I. mytime.o t/year_limit.t.c -o t/year_limit.t 

與錯誤了:

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

因爲是由系統的探頭在構建過程中產生time_config.h,這將是非常方便的在一個頭的所有值保持在一起文件,甚至是多個頭文件。在構建過程中更改.c文件更加困難。

它工作正常,沒有結構。如何在不引起此衝突的情況下在頭文件中聲明最小/最大日期結構?還是我編譯和鏈接不正確?

PS這是ANSI C89。

回答

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

以上聲明並定義了對象SYSTEM_MKTIME_MAX;標題的多個包含導致多個定義。

投入在頭一個extern並且將定義在實現文件。

+2

我認爲'#ifndef TIME_CONFIG_H'受到多重包裹的保護? – Schwern

+1

只有在同一個編譯單元中 - 這些編譯單元是不同的編譯單元,它們定義了符號 –

+1

@Schwern:確實如此,但是SYSTEM_MKTIME_MAX在_different_翻譯單元(即源文件)中定義了兩次,這就是連接器抱怨的原因。 –

4

在你的頭文件(.h),你需要:

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

在您的實現(.C),你需要:

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 }; 
0

頭必須只包含聲明。因此改變頭:

extern const struct tm SYSTEM_MKTIME_MAX; 

而且在CPP使分配

const struct tm SYSTEM_MKTIME_MAX = {... 
+0

注意,我們談論的是C,而不是C++(其中常量具有內部鏈接,因此示例在C++中是有效的),因此可能不是cpp,而是c文件。 –

+0

@Alexander Poluektov既不支持cpp也不支持c聲明關鍵字是「extern」 – Dewfy

+0

1)您混淆了聲明和定義。兩次聲明完全可以接受_both_在C和C++中 –

2

在C常量的外部鏈接,因此應在.c文件中定義。

在C++中它們具有內部鏈接,從而可在報頭中定義。

相關問題