[英]Do useless backslashs produce well-defined string constants?
C 和 C++ 都支持一組看似等效的轉義序列,如\\b
、 \\t
、 \\n
、 \\"
和其他以反斜杠字符 ( \\
) 開頭的轉義序列。如果后面是正常字符,反斜杠如何處理?至於我記得從幾個編譯器中轉義字符\\
被悄悄跳過。在 cppreference.com 上,我閱讀了這些文章
我只找到了這個關於孤兒反斜杠的注釋(在 C 文章中)
如果反斜杠后跟此處未列出的任何字符,則 ISO C 需要診斷:[...]
以上參考表。 我還看了一些在線編譯器
#include <stdio.h>
int main(void) {
// your code goes here
printf("%d", !strcmp("\\ x", "\\ x"));
printf("%d", !strcmp("\\ x", "\\\ x"));
printf("%d", !strcmp("\\ x", "\\\\ x"));
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main() {
cout << (string("\\ x") == "\\ x");
cout << (string("\\ x") == "\\\ x");
cout << (string("\\ x") == "\\\\ x");
return 0;
}
這兩種治療"\\\\ x"
和"\\\\\\ x"
等同,(種)通過語法高亮警告。 IOW "\\\\\\ x"
"\\\\ x"
已轉換為"\\\\ x"
。
我可以假設這是定義的行為嗎?
"\\"
這樣明顯無效的字符串文字。編輯 #2:更加關注不斷生成(和可移植性)。
答案是否定的。 它是一個無效的 C 程序和未指定的C++行為。
說它在語法上是錯誤的(強調是我的),它沒有產生有效的標記,因此程序無效:
5.2.1 字符集
2/在字符常量或字符串文字中,執行字符集的成員應由源字符集的相應成員或由反斜杠 \\ 后跟一個或多個字符組成的轉義序列表示。
6.4.4.4 字符常量
3/單引號 '、雙引號 "、問號 ?、反斜杠 \\ 和任意整數值可根據下表轉義序列表示:
- 單引號'
\\'
- 雙引號“
\\"
- 問號?
\\?
- 反斜杠 \\
\\\\
- 八進制字符
\\octal digits
- 十六進制字符
\\xhexadecimal digits
十六進制\\xhexadecimal digits
8/此外,不在基本字符集中的字符可用通用字符名稱表示,某些非圖形字符可用由反斜杠 \\ 后跟小寫字母組成的轉義序列表示:\\a、\\b、\\f、\\n、 \\r、\\t 和 \\v。 注意:如果任何其他字符跟在反斜杠后面,則結果不是標記並且需要診斷。
不同的說法(強調是我的):
5.13.3 字符字面量
7/某些非圖形字符,單引號'、雙引號"、問號?、25和反斜杠\\,可以根據表8表示。雙引號"和問號?,可以表示作為它們自己或分別由轉義序列 \\" 和 \\?,但單引號 ' 和反斜杠 \\ 應分別由轉義序列 \\' 和 \\ 表示。其中反斜杠后面的字符未在表中列出的轉義序列8 是有條件支持的,具有實現定義的語義。轉義序列指定單個字符。
因此,對於 C++,您需要查看您的編譯器手冊以了解語義,但該程序在語法上是有效的。
您需要使用符合標准的 C 編譯器進行編譯。 各種在線編譯器傾向於使用默認設置為“寬松非標准模式”的 gcc,也就是 GNU C。這可能會或可能不會啟用一些非標准轉義序列,但即使您使用它也不會產生編譯器錯誤違反 C 語言——你可能會得到一個“警告”,但這並不能使代碼成為有效的 C。
如果您使用-std=c17 -pedantic-errors
告訴 gcc 作為符合 C 編譯器的行為, -std=c17 -pedantic-errors
以下錯誤:
error: unknown escape sequence: '\\040'
040 是 32 的八進制,這是' '
的 ASCII 碼。 (出於某種原因,gcc 在內部對轉義序列使用八進制表示法,可能是因為 \\0 是八進制,我不知道為什么。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.