簡體   English   中英

C預處理器如何實際工作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM