2017-01-09 84 views
9

參見下面的例子:爲什麼「foo \ <NEWLINE> bar」在「gcc -E」之後變成「foo bar」?

$ cat foo.c 
int main() 
{ 
    char *p = "foo\\ 
bar"; 
    return 0; 
} 
$ gcc -E foo.c 
# 1 "foo.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "/usr/include/stdc-predef.h" 1 3 4 
# 1 "<command-line>" 2 
# 1 "foo.c" 
int main() 
{ 
    char *p = "foo\bar"; 

    return 0; 
} 
$ 

從我的理解第二\由第一\所以第二\不應與以下<NEWLINE>結合逃到形成續行。

+0

如果你想在c-string中換行,你必須使用''\ n''明確插入它。 – LPs

+0

請參閱http://stackoverflow.com/questions/12694838/defining-a-string-over-multiple-lines – pringi

回答

18

規則是在ISO相當明確的/ IEC 9899:2011§5.1.1.2轉換階段

  • 反斜線字符(\)的每個實例立即然後刪除一個新行 字符,拼接物理源代碼行以形成邏輯源代碼行。 只有任何物理源線上的最後一個反斜槓纔有資格作爲這種拼接的一部分 。
  • 未查閱最終反斜槓前面的字符。階段1將三字母轉換爲常規字符。這很重要,因爲??/\的三元組。

    16

    預處理器在嘗試標記輸入之前刪除所有出現的反斜槓新行,對此沒有逃脫機制。它不限於字符串文字:

    #inclu\ 
    de <st\ 
    dio.h> 
    
    int m\ 
    ain(void) { 
        /\ 
    * yes, this is a comment */ 
        put\ 
    s("Hello,\ 
    world!"); 
        return 0; 
    } 
    

    這是有效的代碼。

    使用\\得到一個單一的\只適用於字符串和字符文字,並在處理後發生很多。

    +0

    可能值得注意的是,讓這一步先於所有其他步驟,可以機械翻譯包含長行的代碼如果系統的最大行長度太短而無法容納它,則翻譯實用程序不必檢查源文件中除換行符以外的任何內容(儘管將文件從使用固定長度記錄的系統轉換爲一個記錄長度較短的系統,代碼將需要確保它只在原始行的內容超過新的最大值的情況下才添加新行)。 – supercat

    相關問題