2013-01-15 182 views
3

我對C相對比較陌生(因爲我不想使用C++,或者至少現在還沒有),我不知道如何解決我的包含錯誤。包含頭文件兩次

我有一個包含常量值爲1000的頭文件,名爲Test。

const int Test = 1000; 

我有這個文件中包含2個文件 - myfile.c文件和Myfile2.c每個包括文件這樣:

#include "MyHeader.h" 

我的項目將無法建立/編譯和我已經找到了它包含頭兩次,這是不允許的,因爲我聲明瞭變量「Test」兩次。經研究,我發現這個維基百科:http://bit.ly/10wPraP

我用這個「包括衛士」

例子:

#ifndef MY_HEADER 
#define MY_HEADER 
const int Test = 1000; 
#endif 

,我也曾嘗試預處理器指令編譯一次(?)。

#pragma once 

但是,我的程序仍然不會構建。我現在得到錯誤,說在MyFile.obj中已經定義了varibale「Test」。

我認爲這可能是一個Visual Studio主題,因爲我正在使用,但我的2010 Express C++和VS2003專業不會建立這個。我已經嘗試在Visual Studio中清理項目,但我不確定還有什麼可做的。

我是否很愚蠢,錯過了一些明顯的東西,這就是爲什麼它不起作用?

我習慣於C#和「使用」命名空間而不是包含。我可以在VS上設置只編譯C代碼來實現這個嗎?

回答

8

包括後衛有什麼用它做。您需要自定義聲明分開,只有一個定義(這就是所謂的「一個定義規則」,ODR):

header.h:

extern const int n; 

一個源文件:

#include "header.h" 

const int n = 1000; 

其他所有源文件:

#include "header.h" 
+0

謝謝!我會盡我所能接受這個答案。我認爲「extern」是一個C++ OO關鍵字,並沒有想到要試試它...... – Ewan

+0

@Kerrek,這讓我很困惑。我完全理解你對ODR的看法,但在我自己的解決方案中,我有一個「定義」頭,基本上是一堆定義爲const const x = 12345;的常量。此標題包含在許多地方。爲什麼它爲我編譯? C++在這方面有什麼不同? (VS2010 btw) –

+0

@ AK4749:在C++中,名稱空間範圍的'const'變量具有內部鏈接(它們隱式地爲'static')。 –

3

有益的參考:

的問題是與頭文件處理方式當你#include它們時:頭文件被直接複製並粘貼到C文件的正文中。這意味着Myfile.c和Myfile2.c都有自己的名爲Test的int聲明 - 實質上創建了兩個不同版本的變量。鏈接器然後抱怨有兩個具有相同名稱的不同變量。

解決的方法是將const int Test = 1000;放入其中一個C文件中,並將extern const int Test;添加到MyHeader.h中。這樣,變量只聲明一次,並且所有文件都知道這一個變量,因爲extern指令告訴他們另一個文件具有他們正在查找的變量Test

MyHeader。^ h

extern const int Test; 

myfile.c文件(例如)

#include "MyHeader.h" 
... 
const int Test = 1000; 

Myfile2.c

#include "MyHeader.h" 
... 
<use Test> 
0

這是正確的。你有兩個源文件定義爲Test。你應該只定義一次。由於頭文件遍佈全國各地,他們通常應該只聲明聲明變量,而不是定義他們。例如

頭:

const int Test;

恰好一個C文件:

const int Test = 1000;

0

定義該變量在.c文件中的任何一個,並聲明作爲頭文件的extern。

#ifndef MY_HEADER 
#define MY_HEADER 
extern const int Test; 
#endif 

Myfile.c定義變量

const int Test = 1000;