单独标头中的#ifdef无法按预期工作

时间:2015-03-10 17:14:25

标签: c++ gcc clang

我在单独的头文件中有#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。)

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

#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.hhttps://github.com/kaspermarstal/SimpleITK/blob/8be437486dce85da271576f866393cd54fe0f865/Code/Common/src/sitkImage.cxx

为什么#ifdef未被#define中的sitkConfigure.h触发?这实际上让我疯狂。如果我将#define SITK_4D_IMAGES直接放在文件中,#ifdef会按预期触发。此外,如果我在#define SITK_4D_IMAGES 1中编写sitkConfigure.h而在其他文件中编写#define SITK_4D_IMAGES 2,编译器会抱怨重新定义SITK_4D_IMAGES,因此它可以清楚地看到文件中的定义包含标题的位置。

使用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重现。

做了一个最小的例子,但无法重现该bug。问题必须与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下载,构建和安装所有依赖项。

1 个答案:

答案 0 :(得分:1)

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