【问题标题】:#ifndef not working as expected#ifndef 没有按预期工作
【发布时间】:2011-11-30 23:17:51
【问题描述】:

为 PAL.h 中的函数指针获取“已在 GUI.obj 中定义”的 LNK2005

//GUI.cpp
#include "PAL.h"

//PAL.h
#define PAL_INCLUDE
int (*addPAL)( int, void(*)(), void(*)() );

//main.cpp
#include "GUI.h"
#ifndef PAL_INCLUDE
#include "PAL.h"
#endif

我是否误解了 include 和 #ifndef 的性质?

【问题讨论】:

  • addPAL 在哪里使用?我假设您要在两个 .cpp 文件之间传递函数

标签: c++ include c-preprocessor


【解决方案1】:

您收到错误可能是因为预处理器在 GUI.cpp 之前处理 main.cpp。 尝试将 PAL.h 的内容更改为:

 #ifndef PAL_INCLUDED
 #define PAL_INCLUDED
 // definitions
 #endif

参考

Include guard

【讨论】:

    【解决方案2】:

    我认为你应该使用include guard 而不是PAL.h

    如果我理解你想要做什么,这段代码会更清晰(并且很常见):

    GUI.h

    #ifndef _GUI_H_
    #define _GUI_H_
    ...
    #endif
    

    GUI.cpp

    #include "PAL.h"
    ...
    

    PAL.h

    #ifndef _PAL_H_
    #define _PAL_H_
    
    int (*addPAL)( int, void(*)(), void(*)() );
    
    #endif
    

    main.cpp

    #include "GUI.h"
    #include "PAL.h"
    ...
    

    希望对您有所帮助。

    【讨论】:

    • 包含守卫是个好主意,但他在定义 addPAL 两次时遇到了链接错误
    • 他这样做是因为他的编译器可能正在编译main.cpp 之前的所有源代码,并且他有多个cpp 文件,包括PAL.h。这样一来,每次他包含 PAL.h 时,他都在重新定义 addPAL,所以我认为我们在谈论同一件事。
    • 两个GUI.cpp和main.cpp是分开编译的(顺序无关)然后在链接时编译器会找到两个addPAL的定义,因为PAL.h都包含在其中。包含守卫仅防止 .h 在一个 .cpp 文件中多次包含
    • 我可能错了,但我认为顺序很重要。据我所知,每当编译器找到#define 预处理器指令时,它的定义就会被推送到符号表中,因此任何条件预处理器指令(#ifndef)都会在该表中查找以进行解析。这样,当您的定义/实现没有得到适当的保护时,顺序会影响是有道理的。
    【解决方案3】:

    Main.cpp 和 GUI.cpp 彼此分开编译,然后链接在一起。这意味着预处理器状态在两次编译之间被重置,并且您丢失了 PAL_INCLUDE 的定义
    标头保护阻止标头被同一编译单元中的其他标头多次包含,而不是防止链接器中的冲突。

    尝试将static 放在方法声明的前面 - 它会将函数限制为当前单元,从而防止出现此问题。 欲了解更多信息,请参阅What is a “static” function?

    【讨论】:

      【解决方案4】:

      addPal 被定义了两次,一次在 GUI.cpp 中,一次在 main.cpp 中。您想要的是定义一次并在需要使用它的任何地方声明它。我建议把

      int (*addPAL)( int, void(*)(), void(*)() );
      

      在其中一个 .cpp 文件中(我没有看到足够多的代码来决定它属于哪一个),然后声明:

      extern int (*addPAL)( int, void(*)(), void(*)() );
      

      在头文件中。 extern 告诉编译器指针 addPAL 存在,但在别处定义

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-19
        • 2020-03-18
        • 2012-06-14
        • 2014-11-15
        • 1970-01-01
        • 2012-07-02
        • 2011-09-07
        • 2013-03-03
        相关资源
        最近更新 更多