【发布时间】:2015-02-13 20:47:16
【问题描述】:
我继承了一个用 C 和 C++ 编写的相当大且复杂的软件包,它使用 gcc 在 Mac OSX Lion 上成功构建:
$> gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
我的任务是使用命令行工具附带的默认 Mac 编译器在 OSX Mavericks 上构建相同的包。
$> gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
OSX Lion 构建完成,但 OSX Mavericks 构建失败并出现以下错误:
Undefined symbols for architecture x86_64:
"_MRIsetVoxVal", referenced from ...
我已使用以下代码块将错误的来源追溯到头文件:
#ifdef __cplusplus
float MRIgetVoxVal( const MRI *mri, int c, int r, int s, int f);
int MRIsetVoxVal(MRI *mri, int c, int r, int s, int f, float voxval);
void MRIdbl2ptr(double v, void *pmric, int mritype);
double MRIptr2dbl(void *pmric, int mritype);
#else
inline float MRIgetVoxVal(const MRI *mri, int c, int r, int s, int f);
inline int MRIsetVoxVal(MRI *mri, int c, int r, int s, int f, float voxval);
inline void MRIdbl2ptr(double v, void *pmric, int mritype);
inline double MRIptr2dbl(void *pmric, int mritype);
#endif
如果我通过简单地删除 if else 和 inline 语句来修改上述代码块,使其如下所示,则构建在两个平台上都完成:
float MRIgetVoxVal( const MRI *mri, int c, int r, int s, int f);
int MRIsetVoxVal(MRI *mri, int c, int r, int s, int f, float voxval);
void MRIdbl2ptr(double v, void *pmric, int mritype);
double MRIptr2dbl(void *pmric, int mritype);
因此,在 OSX Lion 上,ifdef __cplusplus 语句似乎被触发,从而产生了所需的行为。在 Mavericks 上,else 语句被触发,最终导致错误。
如果这是一个非常基本的问题,请原谅我,但 C 和 C++ 超出了我的专业领域。这里发生了什么? #ifdef __cplusplus 到底是什么意思,为什么一个版本的 gcc 会被它触发而另一个版本不会?
【问题讨论】: