2011-11-12 38 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; 

然后在样本定义他们(即分配存储他们的)。通过使用您在表头中使用的表达式。