#if vs #ifndef vs #ifdef

问题描述 投票:0回答:5

我的问题首先是理解

#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
}

但是其他的,虽然我读过,但我无法理解。它们看起来也非常相似,但我怀疑它们的工作原理是否相似。

c++ c preprocessor-directive
5个回答
7
投票

宏由预处理器扩展,预处理器在运行时对变量的值一无所知。它仅涉及文本替换(或比较预处理器已知的符号)。你的线路

#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
,它将非常难以阅读。


5
投票

#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
合理使用。


3
投票

#if
是预处理器
if
。它只能处理预处理器内容,这些内容基本上是预处理器宏(类似函数或类似常量)和具有一些简单整数文字算术的 C 标记。

#ifdef SOMETHING
#if defined(SOMETHING)
相同并且
#ifndef SOMETHING
#if !defined(SOMETHING)
相同。
defined
是一个特殊的预处理器运算符,可让您测试 SOMETHING 是否是已定义的宏。这些基本上是最常见用途或预处理器条件的快捷方式 - 测试是否定义了某些宏。

您可以在以下位置找到有关 gcc 预处理器的详细手册(约 80 页) https://gcc.gnu.org/onlinedocs/ .


0
投票

预处理器 #ifdef 和 #ifndef 的含义如下:在您的示例中,您使用 #define 将名为 LINUX_GRAPHICS 的常量变量设置为等于 011x101。因此,稍后在程序中您可能想要检查该变量是否已定义。然后,当您想要检查该变量是否已定义时,使用#ifdef,如果没有,则使用#ifndef。我希望我能帮助你。


0
投票

基本上,预处理器进行文本替换。然后编译器将程序编译成机器代码。然后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)

© www.soinside.com 2019 - 2024. All rights reserved.