为什么一个带有预处理参数的CC++函数只有在头文件中定义的情况下才能正确链接?

问题描述 投票:0回答:1

我在一个项目中使用CLion(使用CMake),这个项目涉及到一个外部库,它根据宏的定义重新定义类型。 例如,如果定义了标志宏,那么结构类型为 MyType2D 取而代之的是 MyType3D. 我也有两个文件。A.hA.cpp,其中头文件持有一个具有两个函数声明的同名类。f1f2. 两者之间的区别是: f1f2 就是 f1 的参数,其类型未被预处理程序修改,而 f2 的参数,其类型为 MyType3DMyType2D,这取决于是否定义了标志宏。

现在,在构建项目时,在没有定义标志宏的情况下,一切都能正确编译、链接和执行。 当定义了flag宏后,问题就出现了。f2 切换到 MyType3D. 在这种情况下,当我构建项目时,编译成功,但链接失败,并出现错误信息。

Undefined symbols for architecture x86_64:
  "A::f2(MyType3D const*)", referenced from:
      _main in main_3d.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

注意,在编译过程中,对象文件 A.o 我已将其与 main_3d.cpp 在CMake的源列表中。 我也验证了这一点,因为另一个函数。f1,没有抛出任何链接错误,而我恰好在调用 f2.

但是,我不明白的是:如果我。移动定义f1A.cppA.h在定义了flag宏后,代码的编译和运行都符合预期。 为了解决这个问题,我做了以下的尝试。

// ...
#ifdef FlagMacro
    void f1( MyType3D const* var );
#else
    void f1( MyType2D const* var );
#endif
// ...

在这两种情况下... A.hA.cpp (在源文件中定义了适当的函数),但在链接过程中,错误持续存在,并出现了完全相同的信息。

我的问题是:为什么我应该在头文件中定义函数(作为类的一部分。A)时,预处理程序被用来改变函数参数的类型?

c++ cmake c-preprocessor linker-errors clion
1个回答
0
投票

事实证明,这个 FlagMacro 编制时没有定义 A.cpp 变成 A.o. 尽管 FlagMacro 中的一个外部头文件(如 p4est_to_p8est.h)中设置的。main_3d.cpp其中还包括 A.hజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ A.cpp 看不到 FlagMacro 因为我没有一个明确的 #include p4est_to_p8est.hA.h.

© www.soinside.com 2019 - 2024. All rights reserved.