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

#ifdef in separate header not working as expected

本文关键字:工作 单独 #ifdef      更新时间:2023-10-16

我在单独的头文件中有一个 #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.h 和 https://github.com/kaspermarstal/SimpleITK/blob/8be437486dce85da271576f866393cd54fe0f865/Code/Common/src/sitkImage.cxx)

为什么#ifdef不是由sitkConfigure.h中的#define触发的?这简直让我发疯。如果我#define SITK_4D_IMAGES直接放入文件中,则会按预期触发#ifdef。此外,如果我用sitkConfigure.h编写#define SITK_4D_IMAGES 1并在其他文件中编写#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复制。

做了一个最小的示例,但无法重现该错误。问题一定出在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。超级构建下载、构建和安装所有依赖项。

编译器

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