People 推荐#ifdef条件编译大幅提高 https://stackoverflow.com/q/21256252/103167. A 搜索#ifdef https://stackoverflow.com/search?q=%23ifdef证实其使用是普遍的。
Yet #ifdef NAME
(或同等地#if defined(NAME)
以及相关的#ifndef NAME
(and #if !defined(NAME)
)有一个严重的缺陷:
header.h
#ifndef IS_SPECIAL
#error You're not special enough
#endif
源代码.cpp
#include "header.h"
gcc -DIS_SPECIAL 源.cpp
显然,将会过去
源1.cpp
#define IS_SPECIAL 1
#include "header.h"
但是,也会如此
源0.cpp
#define IS_SPECIAL 0
#include "header.h"
这是完全错误的做法。一些 C++ 编译器传递了一个处理过的文件C模式(由于扩展或命令行选项)有效地执行#define __cplusplus 0
。我见过事情破裂的时候
#ifdef __cplusplus
extern "C" {
#endif
/* ... */
#ifdef __cplusplus
}
#endif
被处理于C模式,其中extern "C"
是无效语法,因为__cplusplus
实际上被自动定义为0
.
另一方面,这对于所有编译器来说都是正确的:
#if __cplusplus
extern "C" {
#endif
/* ... */
#if __cplusplus
}
#endif
为什么人们仍然使用#ifdef
在这种情况下?难道他们根本不知道#if
在未定义的名称上工作得很好吗?或者有实际的缺点吗#if
vs #ifdef
用于条件编译?
明显地,#ifdef
确实有有效的用途,例如为可配置参数提供默认值:
#ifndef MAX_FILES
#define MAX_FILES 64
#endif
我只讨论标志测试的情况。