C ++包含警卫似乎不起作用

2022-01-25 00:00:00 include c++

我收到了来自 mbed C++ 编译器的错误消息,这些消息似乎表明包括防护装置出现故障.

I am getting error messages from the mbed C++ compiler that seem to be indicative of malfunctioning include guards.

在 main.cpp 中,我包含如下头文件:

In main.cpp, I include my header file as follows:

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

这是我的示例.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 如下:

In sample.cpp, I am including sample.h as follows:

#include "sample.h"

在 main.cpp 和 sample.cpp 中,我指的是变量 led1, led2, led3, led4 而没有声明它们.但是,编译器会输出这些抱怨:

In both main.cpp and sample.cpp, I am referring to variables led1, led2, led3, led4 without declaring them. However, the compiler is outputting these complaints:

" 符号 led1 多次定义(由 sample.cpp.cpp.LPC1768.o 和 main.cpp.cpp.LPC1768.o)."..." 符号 led4 多次定义(由 sample.cpp.cpp.LPC1768.o 和 main.cpp.cpp.LPC1768.o)."

" Symbol led1 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)." ... " Symbol led4 multiply defined (by sample.cpp.cpp.LPC1768.o and main.cpp.cpp.LPC1768.o)."

我的包含守卫是否写得不正确?还是有其他问题?

Are my include guards written improperly? Or is there some other issue?

(供参考,这里是 链接到 mbed.h 源)

推荐答案

问题在于对包含守卫的作用的误解.包含保护防止编译器再次看到相同的内容在同一个翻译单元(对于同一个 .cpp 文件).他们确实不阻止不同的翻译单元看到相同的代码.

The issue is a misunderstanding of what include guards do. Include guards prevent the compiler from seeing the same content again in the same translation unit (for the same .cpp file). They do not prevent separate translation units from seeing the same code.

在您的头文件中,您定义(不仅仅是声明)变量.因此,每个包含标头的翻译单元都会创建自己的这些变量的副本.

In your header file, you define (not just declare) the variables. Therefore every translation unit which includes the header creates its own copy of those variables.

正确的做法是在 .cpp 文件中定义变量并仅在标头中声明它们(无论如何都应该有包含保护,以防止在同一个翻译单元中多次包含).

The correct way to do it is to define the variables in a .cpp file and only declare them in the header (the include guards should be there anyway, to prevent multiple inclusion in the same translation unit).

也就是说,在你的文件 sample.h 中,在你的变量前面加上 extern 并移除初始化器(所以它们只被声明,而不是定义),并在相应的 .cpp 文件中定义它们(还定义了函数的那个??),通过将标题中的确切定义放在那里.

That is, in your file sample.h, prefix your variables with extern and remove the initializer (so they are only declared, not defined), and define them in the corresponding .cpp file (the one where also the functions are defined), by putting the exact definitions from your header there.

在不相关的注释中,您应该将 sample.h 中的 #include "mbed.h" 放在包含防护中,因为某些编译器会针对此类防护优化编译速度,而该优化不会如果包含警卫之外有材料,则无法工作.请注意,这并不是真正的正确性问题(假设 mbed.h 也受到包含保护的适当保护),而是编译性能问题.

In an unrelated note, you should put the #include "mbed.h" in sample.h inside the include guards, because some compilers optimize compile speed for such guards, and that optimization doesn't work if there's material outside the include guards. Note that this is not really a correctness issue (assuming mbed.h is properly protected by include guards as well), but a compiling performance issue.

相关文章