#ifdef 在单独的 header 中没有按预期工作

#ifdef in separate header not working as expected

我在单独的 header 文件中有一个#define:

#ifndef __sitkConfigure_h
#define __sitkConfigure_h

#define SITK_4D_IMAGES

#endif // __sitkConfigure_h

(完整来源:https://github.com/kaspermarstal/SimpleITK/blob/8be437486dce85da271576f866393cd54fe0f865/Code/Common/src/sitkConfigure.h.in。定义由 #cmakedefine 管理,并在配置 cmake 时按预期变成 #define SITK_4D_IMAGES。)

像往常一样,header 包含在需要配置的地方。例如:

#include "sitkConfigure.h"

#ifdef SITK_4D_IMAGES
/** \brief Constructor for 4D images where pixel type can be specified.
 * @{
 */
Image( unsigned int width, unsigned int height, unsigned int depth, unsigned int length, PixelIDValueEnum valueEnum );
/**@}*/
#endif // #ifdef SITK_4D_IMAGES

#include "sitkConfigure.h"

#ifdef SITK_4D_IMAGES
Image::Image( unsigned int Width, unsigned int Height, unsigned int Depth, unsigned int Length, PixelIDValueEnum ValueEnum )
  : m_PimpleImage( NULL )
{
  Allocate ( Width, Height, Depth, Length, ValueEnum, 0 );
}
#endif // #ifdef SITK_4D_IMAGES

(完整来源:https://github.com/kaspermarstal/SimpleITK/blob/8be437486dce85da271576f866393cd54fe0f865/Code/Common/include/sitkImage.h and https://github.com/kaspermarstal/SimpleITK/blob/8be437486dce85da271576f866393cd54fe0f865/Code/Common/src/sitkImage.cxx

为什么 #ifdef 没有被 sitkConfigure.h 中的 #define 触发?这真的让我发疯。如果我将 #define SITK_4D_IMAGES 直接放在文件中,则会按预期触发 #ifdefs。此外,如果我在 sitkConfigure.h 中写入 #define SITK_4D_IMAGES 1 并在其他文件中写入 #define SITK_4D_IMAGES 2,编译器会抱怨 SITK_4D_IMAGES 的重新定义,因此它可以清楚地看到文件中的定义其中包含 header。

使用 GCC 4.8.9 在 Ubuntu 14.10 上测试,使用 Apple Clang 600.0.56 在 Mac OSX Yosemite 上测试。欢迎大家git clone -b development --single-branch git://github.com/kaspermarstal/SimpleITK.git转载

制作了一个最小示例,但无法重现错误。问题一定出在 SimpleITK 的构建基础设施上。如果有人感兴趣,可以从 dropbox.com/s/zlcnqtx32cq4q22/example.zip?dl=0.

下载

搭建说明:

git clone -b development --single-branch git://github.com/kaspermarstal/SimpleITK.git
mkdir build
cd build
cmake ../SimpleITK/SuperBuild
ccmake .

SITK_4D_IMAGES设置为ON,配置、生成和make -j4。 SuperBuild 下载、构建和安装所有依赖项。

编译器正确处理的 #ifdefs。该问题与使用 SWIG 包装 Python/Java/R/Ruby/Octave/Tcl/Lua/C# 中的接口有关。这些定义没有传递给 SWIG,因此它没有编译 #ifdef 中的内容。将 %include "sitkConfigure.h" 添加到 SWIG .i 文件解决了这个问题。