#if vs #ifndef vs #ifdef

ama*_*el2 5 c c++ preprocessor-directive

我的问题首先是理解#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
}
Run Code Online (Sandbox Code Playgroud)

但其他人,虽然我读到了他们,但我无法理解.它们看似非常相似,但我怀疑它们的工作方式类似.非常感谢帮助.

πάν*_*ῥεῖ 5

#if没有任何概念Compare或它包含的值,所以它可能不会做你想要的.

请记住,预处理器可以替换纯文本.

该声明将扩大,因为看到的#if

#if Compare == 011x101
Run Code Online (Sandbox Code Playgroud)

并被扩展为

#if 0 == 011x101
Run Code Online (Sandbox Code Playgroud)

这肯定不会true在预处理阶段产生.


#ifdef#ifndef指令检查是否有预处理器符号被#define倒是可言,要么使用(< - )预处理指令,或你的编译器预处理程序选项(最常见-D<preprocessor-symbol>).
如果预处理器符号带有空值或其他内容,则不关心这些.一个简单的

#define MY_CONDITION
Run Code Online (Sandbox Code Playgroud)

要么

-DMY_CONDITION
Run Code Online (Sandbox Code Playgroud)

足以满足

#ifdef MY_CONDITION
Run Code Online (Sandbox Code Playgroud)

扩展之后的文本(或隐藏它#ifndef).


Compare声明是不是一个预处理器符号,并且不能合理地与使用#ifdef#ifndef两种.

  • @dsafds:他说的是你可以在`#ifdef`(或`#ifndef`)中使用你喜欢的任何符号.这是真的:要么符号是`#define`'d,在这种情况下`#ifdef`成功而`#ifndef`失败,或者它没有`#define`'d,在这种情况下`#ifdef`失败,`#ifndef`成功.该符号是否稍后将由程序声明*完全无关紧要. (2认同)
  • 通常我觉得有点无聊的帖子,人们使用`srand()`错了,但这次我不介意;) (2认同)

for*_*818 5

宏由预处理器扩展,后者在运行时期间对变量值一无所知.它只是关于文本替换(或比较预处理器已知的符号).你的路线

#if Compare == LINUX_GRAPHICS
Run Code Online (Sandbox Code Playgroud)

将扩大到

#if Compare == 011x101
Run Code Online (Sandbox Code Playgroud)

并且由于"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
Run Code Online (Sandbox Code Playgroud)

我故意写"排除"以强调它对代码可读性的不良影响.如果你过度使用#ifdef#ifndef在正常的代码块内,它将非常难以阅读.

  • tobi303:严格地说,预处理器通过递归扩展所有宏并用"0"替换所有非宏符号(*not*nothing)来工作.然后它尝试将结果计算为仅包含整数常量的算术表达式.结果是`#if NOT_DEFINED == ALSO_NOT_DEFINED`将成功; 这是一个经典的预处理器. (5认同)