[英]Scope rules for C macros
我不是C程序員,但我的假設是C宏幾乎是一種查找和替換功能,其中預處理器采用宏定義並將其放在任何看到宏名稱的位置。
這是Dragon Book的動態范圍規則及其如何應用於宏的示例:
#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
。 我當時以為,它基本上會用(x + 1)
代替a
,然后編譯程序,因此范圍規則將與您編寫(x + 1)
而不是a
(它是靜態的(x + 1)
完全相同。范圍規則)。
有人可以澄清嗎?
編輯:本書指的是《編譯器:原理,技術和工具第二版》。 引用的示例來自第31-32頁。
您的理解是正確的:找到標識符a
每種用法,並用(x + 1)
代替a
。 那正是預處理器所做的。
唯一的“范圍”,我們可以相對於討論的類似對象的宏(例如a
)是宏本身的范圍:一個宏的范圍是從在其上限定的線(用#define
指令)直到未定義的行(使用#undef
指令)或直到轉換單元的末尾(.cpp及其包含的所有標頭)(如果從未定義過)。
您對#define行為的理解是正確的。
我認為這本書在說“動態作用域”時的意思是,名稱x是根據調用宏而不是定義宏的環境解析的。 因此,如果您在#define之前設置了全局變量x = 3,則與#define中的x值無關-在使用宏的任何地方,它都將使用x的值-如果還有其他局部變量使用宏的函數中的變量x,則將使用本地值。
這與詞法作用域(這是C語言以及幾乎所有現代語言中實際使用的詞法作用域)形成對照,后者的名稱指的是其本地詞法環境。 例如,如果您用簡單的語句a = x+1
替換了示例中的#define,則函數中a的值將比出現a = x+1
x碰巧的值多a = x+1
在代碼中。 使用值a時是否還存在其他名為x的局部變量也沒關系。 同樣,如果您定義了一個函數int f() { return x + 1; }
int f() { return x + 1; }
,x會引用全局變量x,而不是在調用f()時存在的其他名為x的局部變量。 如果這似乎令人眼花obvious亂,那是因為,正如我所說,幾乎所有語言都使用詞法作用域(例如,Perl也允許使用local
函數進行動態作用域)。
有關該概念的更多解釋,請參見http://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping_and_dynamic_scoping 。
他們的觀點是,a所指的x在b()中是局部的,而在c()中是全局的-它是動態范圍的。 #define可以解釋為“在評估a時使用動態范圍解析x”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.