說明:
對於比較現代的語言來講字符編碼不是個大問題:java就可以使用中文作為變量名稱,但對於C/C++來講卻不是這樣,由於歷史原因,標准和編譯器廠商的實現總在不停的變化,相關編碼信息到底是如何處理的?對於想知道相關信息的新手來講是很難從現有的書籍和資料上來找到明確的答案。針對這個問題我就自己的理解並結合相關的標准試圖向讀者把這個問題講清楚,由於編譯器眾多,所以重點就放在對標准的解釋以及相關文檔的說明上,具體的實驗和測試請自行操作。
標識符(Identifer)定義(C99和C++2003中的定義是一致的,C89中沒有規定universal-character-name且對標識符長度有規定,C99中不對長度作限定,C++2003規定可以是任意長度):
Syntax
1 identifier: identifier-nondigit
identifier identifier-nondigit identifier digit
identifier-nondigit: nondigit
universal-character-name
other implementation-defined characters
ISO/IEC 9899:1999 (E)
nondigit: one of _ a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
digit: one of 0 1 2 3 4 5 6 7 8 9
從廣義上來講字符編碼實際上有兩種,一種是multibyte,另一種是unicode,multibyte編碼對字符內容的解釋取決於當前系統的區域設置,如windows下的cp936(中文編碼)編碼就是一種multibyte編碼。unicode編碼與系統的當前編碼沒有相關性;在各平台上都應該能正確處理;實際上與UCS編碼(ISO/IEC 10646)是兼容的。unicode是一種編碼方式的統稱,事實上它包含多種編碼如:utf-8,utf-16等。那么對於字符編碼在C語言的相關標准又是怎么規定的呢?ANSI C標准(既C89)明確規定multibyte字符只能應用在字符串字面量,注釋、字符常量這三個方面。對於標識符而言(變量名、函數名等)只能使用基本字符(實際上是26個字母)與數字以及下划線,並且不允許以數字開頭,具體的編譯器至少要能正確處理31個長度的標識符名稱(C89標准 5.2.1.2)。可見早期的編譯器從標准角度來看是無法處理mulibyte和unicode標識符的,但實際上具體的編譯器實現可能作出了擴展以允許標識符字符進行擴展,例如GNU的擴展選項-fextended-identifiers。隨着標准的發展此問題得到了解決,C99標准明確規定multibyte和universal-character-name可以作為標識符的名字(C99標准 5.2.1.2)。至於C++,2003標准只規定了基本拉丁字符、數字、下划線以及universal-character-name,而multibyte由具體的編譯器實現決定。可見由於標准的變化以及相關編譯器的實現異差,在實際工作應該只使用基本的拉丁字符、數字、下划線用作標識符,這樣才能保證可移植性。
相關編譯器信息:
GNU 3.1
http://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Identifiers-implementation.html
Identifiers
- Which additional multibyte characters may appear in identifiers and their correspondence to universal character names (6.4.2).
- The number of significant initial characters in an identifier (5.2.4.1, 6.4.2)
- 更早版本的相關信息無從考證了。如有疑問請自行google。
VS2003:
Visual C++ .NET 2003 Enhanced Compiler Conformance
In this version of the compiler, Unicode characters that cannot be represented in the current system code page are not allowed. The compiler's support for Unicode characters and universal-character-names, as specified in ISO/ANSI Standard, is as follows:
-
Comments
-
String and character literals
-
可見在這個版本支持還是進分有限的,不支持multibyte只支持universal-character-names
VS2005
http://msdn.microsoft.com/zh-cn/library/vstudio/xwy0e8f2(v=vs.100).aspx
可以通過選擇合適的工具以及選擇“啟用 Unicode 響應文件”屬性(默認為啟用)在開發環境中啟用 Unicode 文件名(請參見 如何:打開項目屬性頁)。 有些情況下需要更改此默認值,例如要修改開發環境以便使用不具有 Unicode 支持的編譯器時。
VS2005對multibyte和unicode支持的都很完善了。后繼的VS2008-VS2012與VS2005在此方面基本沒有差異。如果感興趣可另行查找相關資料。
LLVM 3.3
Clang supports Unicode characters in identifiers and its static analyser has added new checkers and can run interprocedural analyses across C++ constructor/destructor boundaries.
最后
事不辯不清,理不論不明。歡迎就此總是一起討論。
