2010-11-27 56 views
9

我不理解下面的程序的輸出:新的__LINE__何時開始?

#include <iostream> 

#define FOO std::cout << __LINE__ << ' ' \ 
         << __LINE__ << '\n'; 
int main() 
{ 
    FOO 

    std::cout << __LINE__ << ' ' \ 
       << __LINE__ << '\n'; 
} 

第一輸出是77,表明FOO膨脹是一個單一的邏輯線,但第二個輸出是910,指示兩條不同的邏輯線。爲什麼有差異?

回答

5

由於

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)中引入,同時將源文件處理爲當前令牌。

雖然通過\結束了線在轉換階段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'; 
} 

這不是有效的代碼,但它演示了事情是如何工作的。應用通常的宏擴展規則,你會得到你得到的輸出。

+0

+1,非常明確的描述 – 2010-11-27 11:27:58

2

導致您在#define語句中定義的語句總是作爲一行進行計算。但是,第二種情況確實是兩行代碼。

3

因爲#define擴展包含hackery以確保__LINE__是宏被「調用」的地方。否則,很多錯誤消息對用戶來說都沒有意義。

+2

這不是hackery。它的行爲與``FOO`擴展之前`#define`在'FOO`中使用的任何其他宏一樣。 `__LINE__`唯一的特殊之處在於它在每一行的開頭自動更新。 – ybungalobill 2010-11-27 11:07:16

0

替換Foo需要評估預定義指令_ _LINE _ _。據我瞭解是因爲,沒有第二個預處理傳球來評估_ _LINE _ _。

因此,_ _line _基於在其上用不了兩年時間美孚線是7

線_ _line _ _在代碼下一行是真正在評估的使用情況進行評估預處理階段基於它出現在翻譯單元源代碼中的確切行號。