简体   繁体   English

#if vs #ifndef vs #ifdef

[英]#if vs #ifndef vs #ifdef

My problem is first of all, understanding #ifndef and #ifdef . 我的问题首先是理解#ifndef#ifdef I also want to understand the difference between #if , #ifndef , and #ifdef . 我也想了解#if#ifndef#ifdef之间的区别。 I understand that #if is basically an if statement. 我知道#if基本上是一个if语句。 For example: 例如:

#include<iostream>
#define LINUX_GRAPHICS 011x101

int main(){
 long Compare = LINUX_GRAPHICS;
 #if Compare == LINUX_GRAPHICS
   std::cout << "True" << std::endl;
 #endif
}

But the others, although I read about them I can't comprehend. 但其他人,虽然我读到了他们,但我无法理解。 They also seem like very similar terms, but I doubt they work similarly. 它们看似非常相似,但我怀疑它们的工作方式类似。 Help would be greatly appreciated. 非常感谢帮助。

#if doesn't have any notion about Compare or the value it contains, so it probably doesn't do what you intend. #if没有关于Compare或它包含的值的任何概念,所以它可能不会按照你的意图行事。

Remember the preprocessor does plain text replacement. 请记住,预处理器可以替换纯文本。

The statement will expand as seen from #if as 该声明将从#if as扩展

#if Compare == 011x101

and being expanded as 并被扩展为

#if 0 == 011x101

which certainly won't yield true at the preprocessing stage. 这肯定不会在预处理阶段产生true


The #ifdef and #ifndef directives check if a preprocessor symbol was #define 'd at all, either using that (<--) preprocessor directive, or your compilers preprocessor option (most commonly -D<preprocessor-symbol> ). #ifdef#ifndef指令检查是否有预处理器符号是#define倒是可言,要么使用(< - )预处理指令,或你的编译器预处理程序选项(最常见的-D<preprocessor-symbol> )。
These don't care if the preprocessor symbol carries an empty value or something. 如果预处理程序符号带有空值或其他内容,则不关心这些。 A simple 一个简单的

#define MY_CONDITION

or 要么

-DMY_CONDITION

is enough to satisfy 足以满足

#ifdef MY_CONDITION

to expand the text coming afterwards (or hide it with #ifndef ). 扩展之后的文本(或用#ifndef隐藏它)。


The Compare declaration isn't a preprocessor symbol and can't be used reasonably with #ifdef or #ifndef either. Compare声明不是预处理器符号,也不能与#ifdef#ifndef合理使用。

Macros are expanded by the preprocessor who doesnt know anything about values of variables during runtime. 宏由预处理器扩展,后者在运行时期间对变量值一无所知。 It is only about textual replacement (or comparing symbols known to the preprocessor). 它只是关于文本替换(或比较预处理器已知的符号)。 Your line 你的路线

#if Compare == LINUX_GRAPHICS

will expand to 将扩大到

#if Compare == 011x101

and as "Compare" is differnt from "011x101", it evaluates to false. 并且由于“Compare”与“011x101”不同,因此评估为false。 Actually I am not even 100% sure about that, but the point is: you are mixing preprocessor directives with variables that are evaluated at runtime. 实际上我甚至不是100%肯定,但重点是:您正在将预处理程序指令与在运行时计算的变量混合。 That is non-sense. 这是无意义的。 Preprocessor directives are not there to replace C++ statements. 预处理程序指令不能替代C ++语句。

For most traditional use cases of macros there are better way nowadays. 对于大多数传统的宏用例,现在有更好的方法。 If you dont really need to use macros, it is better not to use them. 如果你真的不需要使用宏,最好不要使用它们。 It makes it extremly hard to read the code (eg. I dont understand how that macros in your code work and unless I really need it honstely I dont want to know :P) and there are other problems with macros that can lead to very hard to find bugs in your program. 这使得阅读代码非常困难(例如,我不明白代码中的宏是如何工作的,除非我真的需要它,我不想知道:P)并且宏的其他问题可能导致非常困难找到程序中的错误。 Before using macros I would advice you to first consider if there isnt a more natural C++ way of achieving the same. 在使用宏之前,我建议您首先考虑是否有更自然的C ++方法来实现相同的功能。

PS: 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

I wrote "excluded" on purpose to emphazise the bad impact it has on readability of your code. 我故意写“排除”以强调它对代码可读性的不良影响。 If you overuse #ifdef or #ifndef inside normal blocks of code, it will be extremely hard to read. 如果你在正常的代码块中过度使用#ifdef#ifndef ,那么它将非常难以阅读。

#if is preprocessor if . #if是预处理器if It can only deal with with preprocessor stuff which is basically preprocessor macros (which are either function like or constant-like) and C tokens with some simple integer-literal arithmetic. 它只能处理预处理器的东西,它们基本上是预处理器宏(函数类似或类似常量)和带有一些简单整数字算术的C代码。

#ifdef SOMETHING is the same as #if defined(SOMETHING) and #ifndef SOMETHING is the same as #if !defined(SOMETHING) . #ifdef SOMETHING#if defined(SOMETHING)相同, #if defined(SOMETHING) #ifndef SOMETHING#if !defined(SOMETHING) defined is a special preprocessor operator that allows you to test whether SOMETHING is a defined macro. defined是一个特殊的预处理器运算符,允许您测试SOMETHING是否是已定义的宏。 These are basically shortcuts for the most common uses or preprocessor conditionals -- testing whether some macros are defined or not. 这些基本上是最常见用途或预处理器条件的快捷方式 - 测试是否定义了某些宏。

You can find a detailed manual (~80 pages) on the gcc preprocessor at https://gcc.gnu.org/onlinedocs/ . 您可以在https://gcc.gnu.org/onlinedocs/上的gcc预处理器上找到详细的手册(约80页)。

Basicaly, preprocessor does text substitution. Basicaly,预处理器进行文本替换。 Then the compiler compiles program into machine code. 然后编译器将程序编译为机器代码。 And then CPU executes machine instructions. 然后CPU执行机器指令。 This means you can't use preprocessor #if instead of operator if : one does text substitution, while second generates branching code for CPU. 这意味着你不能使用预处理#if ,而不是运营商if :一个做文本替换,而第二生成CPU的分支代码。

So preprocessor directives such as #if , #ifdef , #ifndef serve for "semi-automatic mode" of generating (a little) different programs based on some "meta-input". 因此#if#ifdef#ifndef等预处理器指令用于“半自动模式”,即基于某些“元输入”生成(一点点)不同的程序。 Actually you can always do these substitutions yourself and get working C/C++ program without any preprocessor directives. 实际上,您可以自己进行这些替换,并在没有任何预处理器指令的情况下使用C / C ++程序。 Also compilers often have a command-line switch which outputs just preprocessed program, ie without any #if directives. 编译器通常还有一个命令行开关,它只输出预处理程序,即没有任何#if指令。 Try to play with it, and you should get what these directives do. 尝试使用它,你应该得到这些指令的功能。

#ifdef XXX is just the same as #if defined(XXX) where defined(XXX) is builtin preprocessor-only function which is true when identifier XXX is defined in program text by another preprocessor directive #define . #ifdef XXX#if defined(XXX)相同,其中defined(XXX)内置于仅预处理程序的函数,当标识符XXX在程序文本中由另一个预处理程序指令#define定义时,该函数为true。 And #ifndef XXX is just #if !defined(XXX) . #ifndef XXX只是#if !defined(XXX)

Well the preprocessors #ifdef and #ifndef mean the followind: In your example you used #define to set a constant variable named LINUX_GRAPHICS to be equal to 011x101. 那么预处理器#ifdef和#ifndef意味着followind:在你的例子中,你使用#define将名为LINUX_GRAPHICS的常量变量设置为等于011x101。 So later in your program you migth want to check if this variable is defined. 所以稍后在你的程序中,你想要检查是否定义了这个变量。 Then you use #ifdef, when you want to check if this variable is defined and #ifndef if not. 然后使用#ifdef,如果要检查是否定义了此变量,则使用#ifndef。 I wish I helped you. 我希望我能帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM