我在一个项目中使用CLion(使用CMake),这个项目涉及到一个外部库,它根据宏的定义重新定义类型。 例如,如果定义了标志宏,那么结构类型为 MyType2D
取而代之的是 MyType3D
. 我也有两个文件。A.h
和 A.cpp
,其中头文件持有一个具有两个函数声明的同名类。f1
和 f2
. 两者之间的区别是: f1
和 f2
就是 f1
的参数,其类型未被预处理程序修改,而 f2
的参数,其类型为 MyType3D
或 MyType2D
,这取决于是否定义了标志宏。
现在,在构建项目时,在没有定义标志宏的情况下,一切都能正确编译、链接和执行。 当定义了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
.
但是,我不明白的是:如果我。移动定义 的 f1
从 A.cpp
到 A.h
在定义了flag宏后,代码的编译和运行都符合预期。 为了解决这个问题,我做了以下的尝试。
// ...
#ifdef FlagMacro
void f1( MyType3D const* var );
#else
void f1( MyType2D const* var );
#endif
// ...
在这两种情况下... A.h
和 A.cpp
(在源文件中定义了适当的函数),但在链接过程中,错误持续存在,并出现了完全相同的信息。
我的问题是:为什么我应该在头文件中定义函数(作为类的一部分。A
)时,预处理程序被用来改变函数参数的类型?
事实证明,这个 FlagMacro
编制时没有定义 A.cpp
变成 A.o
. 尽管 FlagMacro
中的一个外部头文件(如 p4est_to_p8est.h
)中设置的。main_3d.cpp
其中还包括 A.h
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ A.cpp
看不到 FlagMacro
因为我没有一个明确的 #include p4est_to_p8est.h
在 A.h
.