c語言中的註釋,multi-line comment
在C/C++語言中, 在對原始檔做預處理的時候,有兩條基本原則: 1、凡是以//開頭的為單行註釋 2、凡是以\結尾的代表此行尚未結束
於是前處理器在處理的時候會先按第二條規則,看每行的末尾的那個字元是不是”\”,是的 話,就下一行接到本行。 然後把所有以//開頭的註釋和/* */的塊註釋去掉。
但是存在一個問題, 對於big5中的漢字而言,其第一個位元組的編碼範圍是0xA1 - 0xFE,第二個位元組是0×40 - 0xFE。而’\'的ASCII碼是0×5c.這就意味這,凡是以big5編碼的檔案,如果gcc沒有正確的 認為它原始檔的編碼是big5,那麼就可能出現因為單行註釋末尾是漢字,而把下行的程式碼 吃掉的情況。這樣是很危險的,但是gcc會給出一個警告:”warning: multi-line
這樣的問題在gbk中同樣存在。 將下面的程式碼 —————————————————————————– //你篭 int main(int argc,char* argv[]){ return 0; } —————————————————————————– 以gbk的方式儲存,並採用gcc 3.4編譯。 無論是solaris 8還是freebsd 6.2,無論shell的locale的設定是zh_CN.GBK還是 zh_CN.UTF-8,所得到的錯誤都是相同的 $ gcc -c testgbk.cpp testgbk.cpp:5: error: expected unqualified-id before “return” testgbk.cpp:6: error: expected declaration before ‘}’ token
g++ 3.3下顯示: testgbk.cpp:3: error: parse error before `return’
原因很簡單,我把“好”字的GBK編碼的後半個位元組改成了’\'的編碼,從而得到了”篭”字。 gcc發現’\'後面接著的就是’\n’,故而把下一行”int main(int argc,char* argv[]){”也 當做註釋一併刪除掉了。
按gcc 3.4的man頁,gcc會根據shell的locale設定來猜測原始檔的編碼格式,否則它會把 其當作utf-8來處理。但是據我在Freebsd和solaris系統中觀察,gcc 3.4並沒有根據環境 變數來猜測原始檔的編碼。
一個不錯的解決方案是,強行給gcc新增-finput-charset=big5這樣的引數,來解決此問 題。類似的還有-fexec-charset,-fwide-exec-charset用於指定執行環境的編碼。但是 不幸的是,gcc內部的處理都是基於utf-8的,且其轉換工作一般是靠系統的iconv轉碼庫來 完成的。 所以系統庫必須提供 GBK<-> UTF-8 、BIG5 <-> UTF-8 的編碼.
例如,我在Freebsd 6.2下使用這樣的引數編譯一個測試檔案: $ gcc -c testbig5.cpp -finput-charset=big5 -fexec-charset=big5 -fwide-exec-charset=big5 所得到的輸出是: cc1plus: no iconv implementation, cannot convert from big5 to UTF-8 cc1plus: no iconv implementation, cannot convert from UTF-8 to big5 cc1plus: no iconv implementation, cannot convert from UTF-8 to big5
所以這種方案的缺點是 1、缺乏通用性,缺乏可移植性。 Freebsd的核心中的轉碼是靠查一個16位的表,所以無法處理utf-8中的漢字(因為漢字是3 位元組),而直到最新的,要到08才能釋出的Freebsd 7.x,此問題也依然沒有被解決。 而Solaris最初的程式碼是基於BSD的。它所提供的iconv轉碼功能也非常差。
2、添加了很多額外的轉碼操作。 目前,utf-8(unicode)尚未完全容納GBK、big5的全部字元。很多字元是轉換不過去的。
另一個折衷的方案是:保證每行註釋都以句號或者空格結尾。 缺點是,需要檢查並改動很多檔案。 且,特殊漢字依然有可能出現在原始檔的常量字串中。問題依舊。 例如 const char* s=”你篭”; 寫成這樣的怪樣子就可以編譯了: const char* s=”你篭”";
較好的解決方案是原始檔都以UTF-8格式編碼。這樣可以最大限度的減少轉碼次數。 最徹底的解決方案是引入gettext,不在原始檔中儲存漢字的常量字串。改用單獨的檔案 儲存。目前包括很多php論壇、blog都已採用這種方案。但是這樣做本來是為了支援英、 法、漢多語言,解決翻譯的問題。如果單為了簡、繁的問題就這麼做,代價太大。