Ben*_*igt 14 c c++ conditional-compilation c-preprocessor
人们建议大范围#ifdef进行条件编译.一个搜索#ifdef证实,它的使用是很普遍的.
然而#ifdef NAME(或等同#if defined(NAME)和相关#ifndef NAME(和#if !defined(NAME))有一个严重的缺陷:
#ifndef IS_SPECIAL
#error You're not special enough
#endif
Run Code Online (Sandbox Code Playgroud)
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
gcc -DIS_SPECIAL source.cpp
显然,将会通过
#define IS_SPECIAL 1
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
但是,也一样
#define IS_SPECIAL 0
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
这是完全错误的事情.而一些C++编译器,传递一个以C模式处理的文件(由于扩展或命令行选项)有效#define __cplusplus 0.我看到事情破裂了
#ifdef __cplusplus
extern "C" {
#endif
/* ... */
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
在C模式下处理,其中extern "C"语法无效,因为__cplusplus实际上是自动定义的0.
另一方面,这适用于所有编译器:
#if __cplusplus
extern "C" {
#endif
/* ... */
#if __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
为什么人们仍然#ifdef在这种情况下使用?他们根本没有意识到#if在未定义的名字上工作得很好吗?或者条件编译对#ifvs 有实际的缺点#ifdef吗?
显然,#ifdef确实有有效用途,例如为可配置参数提供默认值:
#ifndef MAX_FILES
#define MAX_FILES 64
#endif
Run Code Online (Sandbox Code Playgroud)
我只讨论旗帜测试的情况.
为什么人们在这种情况下仍然使用#ifdef?
个人意见:从命令行控制稍微容易一些。我-DOPTION更喜欢-DOPTION=1.
而且,名称的存在显然是二元的。我不必能够处理{0,非零,未定义}。
他们是否只是不知道#if 对于未定义的名称可以完美地工作?
我不知道。这有什么语义?未定义的名称是否假定为 0?我是否需要向一个几乎不了解预处理器的人解释这一点?
或者 #if 与 #ifdef 对于条件编译有实际的缺点吗?
对我来说,名称存在的二元性#ifdef/#ifndef是一个清晰的好处。另外,我对任一构造的主要用途是用于包含防护。那个图案是最干净的#ifndef。