2011-11-12 37 views
2

我從mbed C++編譯器收到錯誤消息,似乎是指示包括警衛在內的故障。C++包括警衛似乎沒有工作

在main.cpp中,我包括我的頭文件如下:

#include "mbed.h" 
#include "sample.h" 

這是我sample.h:

#include "mbed.h" 

#ifndef STUFF_H 
#define STUFF_H 

/* LEDs */ 
DigitalOut led1(LED1); 
DigitalOut led2(LED2); 
DigitalOut led3(LED3); 
DigitalOut led4(LED4); 

/* Subroutines */ 
void sweepLEDs(); 
void pulseLEDs(int numPulses); 
void clearLEDs(); 

#endif 

在sample.cpp的,我包括sample.h爲如下:

#include "sample.h" 

在這兩個的main.cpp和sample.cpp的,我指的是變量led1, led2, led3, led4沒有decla響它們。但是,編譯器正在輸出這些投訴:

「符號led1多次定義(由sample.cpp.cpp.LPC1768.o和main.cpp.cpp.LPC1768.o)」。 ... 「符號led4乘法定義(由sample.cpp.cpp.LPC1768.o和main.cpp.cpp.LPC1768.o)」。

我的包括警衛書寫不當嗎?還是有其他問題?

(僅供參考,這裏是link to the mbed.h source

回答

11

這個問題是一個誤解,包括警衛的做法。包括保護防止編譯器在同一翻譯單元(對於相同的.cpp文件)中再次看到相同的內容。他們做而不是防止單獨的翻譯單位看到相同的代碼。

在你的頭文件中,你的定義了(不只是聲明)變量。因此,包含標題的每個翻譯單元都會創建它們自己的這些變量的副本。

正確的方法是在.cpp文件中定義變量,並只在頭中聲明它們(無論如何,防止包含在同一個翻譯單元中的守衛應該存在)。

也就是說,在文件sample.h中,用extern前綴變量並刪除初始化程序(因此它們只是聲明的,未定義的),並將它們定義在相應的.cpp文件中(也是函數被定義),通過從你的標題確切的定義在那裏。

在一個不相關的說明中,您應該將#include "mbed.h"放在include guard中的sample.h中,因爲有些編譯器會優化此類警衛的編譯速度,並且如果在include guard之外有材料,則優化不起作用。請注意,這不是一個真正的正確性問題(假設mbed.h已被include guard保護),但是編譯性能問題。

4

您需要標記聲明爲「extern」是這樣的:

extern DigitalOut led1; 

然後在樣本定義他們(即分配存儲他們的)。通過使用您在表頭中使用的表達式。