条件预处理难题
Conditional preprocessing puzzle
我遇到了一个问题,似乎无法让条件#define预处理器正常工作。例如:
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "stdafx.h"
#else
#define PCH "xyz.h"
#endif
#include PCH
如果我使用这个表单,编译器告诉我它找不到"stdafx.h"。好吧,这看起来很奇怪,所以如果我把代码改为…
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "xyz.h"
#else
#define PCH "stdafx.h"
#endif
#include PCH
然后,PCH中定义的文件被提取出来,一切都编译得很好。这对我来说似乎很奇怪,就像预处理器忽略了#if指令,只使用了它遇到的所有#定义一样。
很明显,我做错了什么,我希望有人能帮助我理解这一点。
当项目启用了预编译头功能时,预处理器会忽略#include"stdafx.h"之前的所有内容
因此,您的#define语句将被忽略。
TL:DR;#define
定义符号,#ifdef
测试符号是否定义,而不是它是否有值。
#define WIN32_BUILD
这定义了一个预处理器令牌WIN32_BUILD。令牌没有值。在任何使用令牌"WIN32_BUILD"的地方,预处理器都会替换空字符串,即什么都不替换。
#ifdef WIN32_BUILD
这将检查是否定义了预处理器令牌WIN32_BUILD。是的,你刚刚定义了它。
#ifdef WIN32_BUILD
// true - this code is included.
#define PCH "stdafx.h"
这定义了预处理器令牌PCH,并为其分配值"stdafx.h"
#else
#define PCH "xyz.h"
#endif
此代码被忽略,因为定义了WIN32_BUILD。
看起来,如果表达式没有定义/to/something,那么您希望"ifdef"只计算为true。
#define a
#define b SOMETHING
#ifdef a
// you are expecting this to be ignored
#endif
#ifdef b
// and expecting this not to be ignored
#endif
CCD_ 3和CCD_。
#define a
#define b SOMETHING
#if defined(a) && defined(b)
// this code will be evaluated, both tokens are defined.
#endif
预处理器令牌的这一功能通常用于支持条件功能:
#if HAVE_CPP11_OVERRIDE_KEYWORD
#define OVERRIDE_FN override
#else
#define OVERRIDE_FN
#endif
struct A {
virtual void foo() {}
};
struct B : public A {
void foo() OVERRIDE_FN {}
};
在上面的代码中,只有在系统支持的情况下(在代码之外确定),才会添加override
关键字。
因此,使用override
的编译器可以看到
struct B : public A {
void foo() override {}
};
没有它的编译器会看到
struct B : public A {
void foo() {}
};
注意:与"ifdef"相对的是"ifndef":
#define a
#define b SOMETHING
#undef c
//#define d // << we didn't define it.
int main() {
#ifdef a
#pramga message("a is defined")
#else
#pramga message("a is UNdefined")
#endif
#ifdef b
#pragma message("b is defined")
#else
#pramga message("b is UNdefined")
#endif
#ifdef c
#pramga message("c is defined")
#endif
#else
#pramga message("c is UNdefined")
#endif
#ifdef d
#pramga message("d is defined")
#endif
#else
#pramga message("d is UNdefined")
#endif
#ifndef d
#pragma message("d is not defined")
#endif
#ifndef a
#pragma message("a is not defined")
#endif
return 0;
}
您可以为预处理器令牌分配数值,并使用#if
进行测试
#if _MSC_VER
#define WIN32_BUILD 1
#else
#define WIN32_BUILD 0
#endif
#if WIN32_BUILD
#include <Windows.h>
#endif
但是,尤其是在进行跨平台编程时,人们倾向于使用ifdef
变体,而不是数字检查,因为值检查要求您明确确保所有令牌都定义有值。只在需要的时候定义它们要容易得多。
- 错误:无效的预处理指令 #i 的意思是 #if?
- C++预处理会生成变量成员、资源库和映射
- 使用预处理指令检查是否包含标头?
- 预处理的 C/C++ 文件是否特定于计算机?
- 使用 GCC 对 C 文件进行部分预处理(不删除 "define" 指令)
- 在 CPLEX 中求解线性规划,无需剪切和预处理
- CPP -D 选项,用于预处理 Fortran 代码
- 错误:粘贴"tmp_UINT"和"+"未提供有效的预处理令牌
- 任务计划程序库的预处理不起作用 - 多定义错误
- Eclipse 问题 - 编译期间不考虑 .c 和 .cpp 文件中定义的预处理
- 使用python预处理后,C++(opencv)中的垫子类型数据与image_to_array相同
- Howo 使用 cl 预处理为 masm 组装生成一个单独的文件
- 我有一个预处理的 C/C++ 源文件 (cacti.i).如何从这个 .i 文件生成可执行二进制文件,以便我可以像 ./
- 如何使用Visual Studio C/C++编译器(cl.exe)来预处理我的objective-C代码
- 是具有预处理前分支实现的结构违反ODR
- 与不完整的Cholesky预处理的共轭梯度返回特征库的意外错误
- Visual Studio C - 无法输出预处理文件
- 在海湾合作委员会中加快宏观预处理的任何方法
- Xmllint未设置,而在路径中找不到XMLLINT;跳过XML预处理
- 条件预处理难题