【问题标题】:C++ include guards do not seem to be workingC ++包含警卫似乎不起作用
【发布时间】:2011-11-13 06:42:48
【问题描述】:

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

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

#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 如下:

#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

【问题讨论】:

    标签: c++ include


    【解决方案1】:

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

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

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

    也就是说,在您的文件 sample.h 中,在您的变量前面加上 extern 并删除初始化程序(因此它们仅被声明,未定义),并在相应的 .cpp 文件中定义它们(其中还有函数已定义),通过将标题中的确切定义放在那里。

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

    【讨论】:

      【解决方案2】:

      您需要将声明标记为“extern”,如下所示:

      extern DigitalOut led1;
      

      然后使用您在标头中使用的表达式在 sample.cpp 中定义它们(即为它们分配存储空间)。

      【讨论】:

        猜你喜欢
        • 2011-12-17
        • 1970-01-01
        • 2018-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多