C宏的范围规则 [英] Scope rules for C macros
问题描述
我不是C程序员,但我的假设是C宏几乎是一种查找和替换功能,其中预处理器采用宏定义并将其放在任何看到宏名称的位置.
I'm not much of a C programmer, but I was under the assumption that C macros were almost sort of a find and replace feature where the pre-processor takes the macro definition and puts it wherever it sees the macro name.
这是《龙之书》中动态范围规则的示例,以及它们如何应用于宏:
This is the Dragon Book's example of dynamic scope rules and how they apply to macros:
#define a (x + 1)
int x = 2;
void b () { int x = 1; printf("%d\n", a); }
void c () { printf("%d\n", a); }
void main () { b(); c(); }
他们还讨论了动态范围规则如何应用于宏a
中的名称x
.我以为它基本上是将a
替换为(x + 1)
然后编译程序,因此范围规则将与您编写(x + 1)
而不是a
完全相同(这是静态的)范围规则).
They also discuss how dynamic scope rules apply to the name x
within macro a
. I was under the assumption that it would basically replace a
with (x + 1)
and then compile the program and so the scope rules would be exactly the same as if you had written (x + 1)
instead of a
(which would be static scope rules).
有人可以澄清吗?
所指的书是编译器:原理,技术和原理.工具第二版.引用的示例来自第31-32页.
Book referred to is Compilers: Principles, Techniques & Tools Second Edition. The example quoted is from pages 31-32.
推荐答案
您对#define行为的理解是正确的.
Your understanding of the #define behaviour is correct.
我认为这本书在说动态范围"时的意思是,名称x是根据调用宏而不是定义宏的环境解析的.因此,如果您在#define之前设置了全局变量x = 3,则该值与#define中的x值无关-在使用宏的任何地方它都将使用x的值-如果还有其他局部变量使用宏的函数中的变量x,将使用本地值.
What I think the book means when it says "dynamic scoping" is that the name x is resolved based on the environment where the macro is called, not where it is defined. So if you've set a global variable x=3 just before your #define, that's irrelevant to the value of x in the #define - it will just use the value of x wherever you use the macro - if there is some other local variable x in the function where you use the macro, then the local value will be used.
这与词法作用域(这是C语言以及几乎所有现代语言中实际使用的词法作用域)形成对比,在词法作用域中,名称是指其本地词法环境.例如,如果用简单的语句a = x+1
替换了示例中的#define,则函数中a的值将比代码中出现a = x+1
时x处的x值多一个.使用值a时是否还存在名为x的其他局部变量也没关系.同样,如果定义函数int f() { return x + 1; }
,则x将引用全局变量x,而不是在调用f()时恰好存在的其他名为x的局部变量.如果这似乎令人眼花obvious乱,那是因为,正如我所说,几乎所有语言都使用词法作用域(例如,Perl也允许使用local
函数进行动态作用域).
This is in contrast to lexical scoping (which is what is actually used in the C language, and in almost all modern languages), in which a name refers to its local lexical environment. For example, if you replaced the #define in your example by the simple statement a = x+1
, then the value of a in the function would be one more than whatever x happened to be at the point where a = x+1
appears in the code. It wouldn't matter if some other local variable named x happened to exist at the point where you use the value a. Similarly, if you defined a function int f() { return x + 1; }
, x would refer to the global variable x, not some other local variable named x that happens to exist where f() is called. If this seems blindingly obvious, it's because, as I said, pretty much all languages use lexical scope (although Perl, for example, also allows dynamic scope using the local
function).
请参见 http://en.wikipedia.org/wiki/Scope_(computer_science) #Lexical_scoping_and_dynamic_scoping 有关该概念的更多解释.
See http://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping_and_dynamic_scoping for a bit more of an explanation of the concept.
这篇关于C宏的范围规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!