#ifdef MACRO是否等于注释 [英] Is #ifdef MACRO equivalent to a comment

查看:186
本文介绍了#ifdef MACRO是否等于注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设未定义MACRO,它们是否等效

Assuming that MACRO is not defined, are these equivalent

#ifdef MACRO
    Not valid C or C++ code
#endif

/*
    Not valid C or C++ code
*/

在GCC 4.7.1中,这似乎是等效的,但是是否有预处理器可以做更多的事情?

In GCC 4.7.1, it seems to be equivalent but are there preprocessors that do more?

推荐答案

这取决于您所说的无效的C或C ++代码的含义。

It depends on what you mean by "not valid C or C++ code".

注释 中的文本没有符合大多数语言规则。它甚至没有被标记化。这是完全正确的:

Text inside a comment does not have to conform to most of the rules of the language. It isn’t even tokenized. This is perfectly valid:

/* This comment doesn't contain a valid sequence of preprocessing tokens
   (because of the apostrophe).  */

它唯一必须遵守的规则是控制注释结束位置的规则。人们经常在行注释中被反斜杠换行符绊倒(请注意,SO的语法突出显示功能会出错!)

The only rules it does have to obey are the ones that control where the comment ends. People regularly get tripped up by backslash-newline in line comments (note that SO's syntax highlighter gets this wrong!)

// Line comment with ascii art ending with a \
   Oops! This line is commented out too!

并较少使用(不只是因为每个C教程都会警告您)块注释而不嵌套(语法荧光笔可以正确显示这一点):

and less often (if only because every C tutorial warns you about this) by block comments not nesting (the syntax highlighter gets this one right):

/* you can't nest /* block comments */ these words are not commented */

另一方面,跳过的预处理器有条件的组 确实必须符合该语言的某些规则。标准(C99§6.10.1p5)的确切字眼是

On the other hand, text inside a "skipped" preprocessor conditional "group" does have to conform to some of the rules of the language. The exact words of the standard (C99 §6.10.1p5) are


按顺序检查每个指令的条件。如果评估结果为假(零),则它控制的组
将被跳过:伪指令仅通过确定伪指令
的名称进行处理,以便跟踪嵌套条件的级别。
指令的其余预处理令牌以及
组中的其他预处理令牌都会被忽略。

Each directive’s condition is checked in order. If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive in order to keep track of the level of nested conditionals; the rest of the directives’ preprocessing tokens are ignored, as are the other preprocessing tokens in the group.

有两个重要的位。首先,对文本 进行标记,因此确实必须是有效的预处理标记序列。

There are two important bits. First, the text is tokenized, so it does have to be a valid sequence of preprocessing tokens.

#if 0
This skipped conditional group doesn't contain a valid sequence of
preprocessing tokens (because of the apostrophe).
#endif

是语法错误。

$ gcc -fsyntax-only test.c
test.c:2:37: warning: missing terminating ' character
 this skipped conditional group doesn't contain a valid sequence of
                                     ^

第二,指令仍在以便跟踪嵌套条件的级别,这表示您可以执行以下操作:

Second, directives are still partially processed "in order to keep track of the level of nested conditionals", which means you can do this:

#if 0 // forget this entire mess
    #ifdef __linux__
    do_linux_specific_thing();
    #elif defined __APPLE__
    do_osx_specific_thing();
    #elif defined _WIN32
    do_windows_specific_thing();
    #endif
#endif

而您不能 this

    #ifdef __linux__
    do_linux_specific_thing();
    #elif defined __APPLE__
    do_osx_specific_thing();
#if 0 // forget windows
    #elif defined _WIN32
    do_windows_specific_thing();
    #endif
#endif

(不会出现错误最后,但是...

(You won’t get an error for that last, but…

$ gcc -E -P -U__linux__ -D__APPLE__ -D_WIN32 test.c
    do_osx_specific_thing();
    do_windows_specific_thing();

…我不认为那是谁写的

许多语言指南告诉您使用 #if 0 来注释掉您要暂时禁用的大部分代码。他们之所以这样说是因为块注释不会嵌套。如果您尝试用一段注释禁用代码区域,但该区域内有一块注释,则注释输出将过早终止,并且代码可能无法编译。在C没有行注释的时代,这一点尤为重要。

Many guides to the language tell you to use #if 0 to "comment out" large regions of code that you want to disable temporarily. They say this because block comments don‘t nest. If you try to disable a region of code with a block comment, but there’s a block comment inside that region, the commenting-out will end prematurely and probably the code will fail to compile. This was more important in the days when C didn’t have line comments; some projects use only line comments for commentary, reserving block comments for disabling code.

但是由于在 #if 0 … #endif 仍是标记化的,并且嵌套的预处理条件必须仍然保持平衡,因此您必须对放置 #if的位置稍加小心0 #endif 。通常这不是问题,因为在禁用代码之前,该代码曾用于编译,因此其中不应包含任何内容以引起令牌化错误。

But because code inside #if 0#endif is still tokenized, and nested preprocessor conditionals must still balance, you do have to be a little careful about where you put the #if 0 and the #endif. It’s usually not a problem, because the code used to compile before you disabled it, so it shouldn’t have anything in it to cause a tokenization error.

这篇关于#ifdef MACRO是否等于注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆