怎样的C preprocessor处理循环依赖? [英] How does the C preprocessor handle circular dependencies?

查看:134
本文介绍了怎样的C preprocessor处理循环依赖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道在 C preprocessor如何处理循环依赖(#定义的)。这是我的程序:

I want to know how the C preprocessor handles circular dependencies (of #defines). This is my program:

#define ONE TWO 
#define TWO THREE
#define THREE ONE

int main()
{
    int ONE, TWO, THREE;
    ONE = 1;
    TWO = 2;
    THREE = 3;
    printf ("ONE, TWO, THREE = %d,  %d, %d \n",ONE,  TWO, THREE);
}

下面是preprocessor输出。我无法弄清楚,为什么输出是这样。我想知道的各个步骤的preprocessor发生在这种情况下,给下面的输出。

Here is the preprocessor output. I'm unable to figure out why the output is as such. I would like to know the various steps a preprocessor takes in this case to give the following output.

# 1 "check_macro.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "check_macro.c"

int main()
{
 int ONE, TWO, THREE;
 ONE = 1;
 TWO = 2;
 THREE = 3;
 printf ("ONE, TWO, THREE = %d,  %d, %d \n",ONE, TWO, THREE);
}

我在Linux上运行此程序3.2.0-49-仿制PAE和gcc版本4.6.3编译(Ubuntu的/ Linaro的4.6.3-1ubuntu5)。

I'm running this program on linux 3.2.0-49-generic-pae and compiling in gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5).

推荐答案

虽然preprocessor宏正在扩大,即宏的名称不扩大。所以,你的符号的全部三个被定义为自己的:

While a preprocessor macro is being expanded, that macro's name is not expanded. So all three of your symbols are defined as themselves:

ONE -> TWO -> THREE -> ONE (not expanded because expansion of ONE is in progress)
TWO -> THREE -> ONE -> TWO (        "                         TWO      "        )
THREE -> ONE -> TWO -> THREE (      "                         THREE    "        )

此行​​为是由与教派设置; C标准的6.10.3.4(从C11草案章节号,虽然身为据我所知,该科的措辞和编号不变,因为C89)。当遇到一个宏的名字,它被替换为它定义(和 ## preprocessor运营商被处理,以及作为参数函数宏)。然后将结果重新扫描为多个宏(在文件的其余部分的情况下):

This behaviour is set by §6.10.3.4 of the C standard (section number from the C11 draft, although as far as I know, the wording and numbering of the section is unchanged since C89). When a macro name is encountered, it is replaced with its definition (and # and ## preprocessor operators are dealt with, as well as parameters to function-like macros). Then the result is rescanned for more macros (in the context of the rest of the file):

2 /如果此扫描替换列表(不包括源文件的preprocessing令牌的其余部分)的过程中发现被替换的宏的名称,所以不能更换。此外,如果任何嵌套替换遇到宏的名称被替换,它不替换&hellip;

2/ If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced…

该条款接着说,这是不是因为递归调用替换任何标记有效地冻结:它永远不会被替换:

The clause goes on to say that any token which is not replaced because of a recursive call is effectively "frozen": it will never be replaced:

&hellip;这些nonreplaced宏的名称preprocessing令牌不再为他是在该宏的名称preprocessing令牌否则将被替换背景下进一步检查更换,即使他们以后(重新)。

… These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

其中最后一句是指在实际中很少出现,但这里的情况是我能想到的最简单的例子:

The situation which the last sentence refers rarely comes up in practice, but here is the simplest case I could think of:

#define two one,two
#define a(x) b(x)
#define b(x,y) x,y
a(two)

结果是一,二两个被扩展为一,二更换期间 A 和扩大两个标记为完全展开。随后, B(一,二)扩展。这已不再是更换两个的背景下,但两个这是第二个参数 b 已被冻结,所以它不会再次扩大。

The result is one, two. two is expanded to one,two during the replacement of a, and the expanded two is marked as completely expanded. Subsequently, b(one,two) is expanded. This is no longer in the context of the replacement of two, but the two which is the second argument of b has been frozen, so it is not expanded again.

这篇关于怎样的C preprocessor处理循环依赖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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