我从mbed 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
而没有声明它们。但是,编译器正在输出这些抱怨:
“符号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)
答案 0 :(得分:12)
问题在于对包括警卫在内的内容的误解。包含防护可防止编译器在同一翻译单元中再次看到相同的内容(对于相同的.cpp文件)。他们不阻止单独的翻译单位看到相同的代码。
在头文件中,您定义(而不仅仅是声明)变量。因此,包含标题的每个翻译单元都会创建自己的变量副本。
正确的方法是在.cpp文件中定义变量,并且只在标题中声明它们(无论如何都应该包含防护,以防止多次包含在同一个翻译单元中)。
也就是说,在你的文件sample.h中,用extern
为变量添加前缀并删除初始化程序(因此它们只是声明,未定义),并在相应的.cpp文件中定义它们。通过在标题中输入确切的定义来定义函数。
在一个不相关的注释中,你应该将#include "mbed.h"
放在include.h中的sample.h中,因为有些编译器可以优化这些防护的编译速度,并且如果包含防护之外的材料,则优化不起作用。请注意,这不是一个真正的正确性问题(假设mbed.h也受到包含警卫的适当保护),但是编译性能问题。
答案 1 :(得分:4)