我的问题首先是理解
#ifndef
和#ifdef
。我还想了解 #if
、#ifndef
和 #ifdef
之间的区别。我知道 #if
基本上是一个 if 语句。例如:
#include <iostream>
#define LINUX_GRAPHICS 011x101
int main() {
long Compare = LINUX_GRAPHICS;
#if Compare == LINUX_GRAPHICS
std::cout << "True" << std::endl;
#endif
}
但是其他的,虽然我读过,但我无法理解。它们看起来也非常相似,但我怀疑它们的工作原理是否相似。
宏由预处理器扩展,预处理器在运行时对变量的值一无所知。它仅涉及文本替换(或比较预处理器已知的符号)。你的线路
#if Compare == LINUX_GRAPHICS
将扩展到
#if Compare == 011x101
并且由于“Compare”与“011x101”不同,因此其计算结果为 false。实际上,我对此甚至不是 100% 确定,但要点是:您将预处理器指令与在运行时评估的变量混合在一起。那是无意义的。预处理器指令不能替代 C++ 语句。
对于大多数传统的宏用例,现在有更好的方法。如果你确实不需要使用宏,最好不要使用它们。这使得阅读代码变得非常困难(例如,我不明白代码中的宏是如何工作的,除非我真的需要它,否则我不想知道:P)并且宏还存在其他问题导致很难在程序中找到错误。在使用宏之前,我建议您首先考虑是否没有更自然的 C++ 方法来实现相同的目的。
PS:
#ifdef SYMBOL
ifdef = "if defined"
this part of the code is excluded before the compiler even sees it
if SYMBOL is not defined (via #define)
#endif
#ifndef SYMBOL
ifndef = "if not defined"
this part of the code is excluded before the compiler even sees it
if SYMBOL is defined (via #define)
#endif
我故意写“排除”是为了强调它对代码可读性的不良影响。如果您在正常代码块中过度使用
#ifdef
或 #ifndef
,它将非常难以阅读。
#if
对 Compare
或其包含的值没有任何概念,因此它可能不会达到您的预期。
记住预处理器会进行纯文本替换。
该声明将扩展为
#if
as
#if Compare == 011x101
并扩展为
#if 0 == 011x101
在预处理阶段肯定不会产生
true
。
#ifdef
和 #ifndef
指令检查预处理器符号是否已被 #define
处理,或者使用它 (<--) preprocessor directive, or your compilers preprocessor option (most commonly -D<preprocessor-symbol>
)。#define MY_CONDITION
或
-DMY_CONDITION
足以满足
#ifdef MY_CONDITION
展开随后的文本(或使用
#ifndef
隐藏它)。
Compare
声明不是预处理器符号,也不能与#ifdef
或#ifndef
合理使用。
#if
是预处理器if
。它只能处理预处理器内容,这些内容基本上是预处理器宏(类似函数或类似常量)和具有一些简单整数文字算术的 C 标记。
#ifdef SOMETHING
与 #if defined(SOMETHING)
相同并且
#ifndef SOMETHING
与 #if !defined(SOMETHING)
相同。 defined
是一个特殊的预处理器运算符,可让您测试 SOMETHING 是否是已定义的宏。这些基本上是最常见用途或预处理器条件的快捷方式 - 测试是否定义了某些宏。
您可以在以下位置找到有关 gcc 预处理器的详细手册(约 80 页) https://gcc.gnu.org/onlinedocs/ .
预处理器 #ifdef 和 #ifndef 的含义如下:在您的示例中,您使用 #define 将名为 LINUX_GRAPHICS 的常量变量设置为等于 011x101。因此,稍后在程序中您可能想要检查该变量是否已定义。然后,当您想要检查该变量是否已定义时,使用#ifdef,如果没有,则使用#ifndef。我希望我能帮助你。
基本上,预处理器进行文本替换。然后编译器将程序编译成机器代码。然后CPU执行机器指令。这意味着您不能使用预处理器
#if
代替运算符 if
:一个进行文本替换,而第二个为 CPU 生成分支代码。
因此,诸如
#if
、#ifdef
、#ifndef
之类的预处理器指令用于基于某些“元输入”生成(一点)不同程序的“半自动模式”。实际上,您始终可以自己进行这些替换并获得可工作的 C/C++ 程序,而无需任何预处理器指令。此外,编译器通常有一个命令行开关,它仅输出预处理的程序,即没有任何 #if
指令。尝试使用它,您应该了解这些指令的作用。
#ifdef XXX
与 #if defined(XXX)
相同,其中 defined(XXX)
是仅内置预处理器函数,当另一个预处理器指令 #define
在程序文本中定义标识符 XXX 时,该函数为 true。 #ifndef XXX
只是 #if !defined(XXX)
。