[英]How does C preprocessor actually work?
我讓代碼片段更容易解釋
// Example 1
#define sum2(a, b) (a + b)
#define sum3(a, b, c) (sum2(a, sum2(b, c)))
sum3(1, 2, 3) // will be expanded to ((1 + (2 + 3)))
// Example 2
#define score student_exam_score
#define print_score(student_exam_score) printf("%d\n", score)
#undef score
print_score(80); // will be expanded to printf("%d\n", score);
// but not printf("%d\n", 80); that I expect
第一個是直觀的,並且在幾個地方存在各種代碼,例如找到最大或最小數量。 但是,我想使用該技術使我的代碼清晰易讀,所以我用一個更短更有意義的名稱替換宏中的一些單詞。
AFAIK,C預處理器每個編譯單元只運行一次,只執行字符串替換,但為什么print_score
不能擴展為printf("%d\\n", 80);
?
這是我猜的替換程序:
#define score student_exam_score
#define print_score(student_exam_score) printf("%d\n", score)
#undef score
print_score(80);
// -->
#define score student_exam_score // runs this first
#define print_score(student_exam_score) printf("%d\n", student_exam_score) // changed
#undef score
print_score(80);
// -->
#define score student_exam_score
#define print_score(student_exam_score) printf("%d\n", student_exam_score) // then this
#undef score
printf("%d\n", 80); // changed
這是一個排序問題。 首先定義宏,並且在使用之前score
是未定義的。 然后,當print_score
被展開時,它首先替換student_exam_score
所有實例,其中沒有。 然后重新掃描結果,尋找進一步擴展的宏,但由於score
未定義且不再可用,因此沒有。
即使您將#undef score
降低到低於print_score
的引用,它仍然無法工作,因為參數替換只發生一次( score
將被擴展,但student_exam_score
不會)。
請注意,在定義時, score
不會替換為print_score
的主體。 僅在宏被實例化時才發生替換,這就是為什么#undef score
導致score
宏沒有任何影響的原因。
這些例子將使它更清晰。 首先,請考慮以下事項:
#define foo bar
#define baz(bar) (foo)
baz(123)
這擴展如下:
baz(123)
-> (foo)
-> (bar)
擴張在這里停止。 參數替換是在foo
擴展之前完成的,並且不會再次發生。
現在考慮以下內容:
#define foo bar
#define baz(bar) (foo)
#undef foo
baz(123)
這擴展如下:
baz(123)
-> (foo)
擴展在此處停止,因為不再定義foo
。 它的早期定義對baz
的定義沒有影響,因為在定義宏時不會發生宏替換。 它只會在擴展時發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.