[英]When does a new __LINE__ start?
我不明白以下程序的輸出:
#include <iostream>
#define FOO std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
int main()
{
FOO
std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
}
第一個輸出是7
和7
,表示FOO
的擴展是單個邏輯行,但第二個輸出是9
和10
,表示兩個不同的邏輯行。 為什么會有區別?
因為
1: #include <iostream>
2:
3: #define FOO std::cout << __LINE__ << ' ' \
4: << __LINE__ << '\n';
5: int main()
6: {
7: FOO // the first two __LINE__s come from here, that's one line of code
8:
9: std::cout << __LINE__ << ' ' \ // 3rd __LINE__ comes from here
10: << __LINE__ << '\n'; // 4th __LINE__ comes from here
11: }
__LINE__
擴展為物理線,而不是邏輯線:
在將源文件處理為當前令牌時,當前源行的行號比在轉換階段1(2.2)中讀取或引入的換行符號的數量大1。
以\\
結尾的行在翻譯階段2中連接。
另一個唯一的邏輯實現是打印3和4來調用FOO,但這似乎不是很有用。
您還可以通過以下方式查看: __LINE__
與任何其他宏沒有任何不同。 它只是由編譯器在每一行的開頭自動更新。 所以代碼是這樣解釋的:
#include <iostream>
#define __LINE__ 3
#define FOO std::cout << __LINE__ << ' ' \
<< __LINE__ << '\n';
int main()
{
#define __LINE__ 7
FOO
#define __LINE__ 9
std::cout << __LINE__ << ' ' \ // Yeah, you're right
#define __LINE__ 10
<< __LINE__ << '\n';
}
這不是有效的代碼,但它演示了事情是如何工作的。 應用通常的宏擴展規則,您將獲得您已獲得的輸出。
因為#define
擴展包含hackery以確保__LINE__
是“調用”宏的那個。 否則,許多錯誤消息對用戶沒有意義。
導致你在#define
語句中定義的一個總是被評估為一行。 但是,第二種情況實際上是兩行代碼。
替換Foo需要評估預定義指令_ _LINE _ _。 據我所知,這是因為,沒有第二個預處理過程來評估_ _LINE _ _。
因此,_ _LINE _ _基於Foo被顯示的行(即第7行)進行評估。
在代碼的后續行中_ _LINE _ _的使用實際上是在預處理階段根據它在翻譯單元的源代碼中出現的確切行號進行評估的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.