如何使GCC支援中文(utf-8)的變數名、函式名?
阿新 • • 發佈:2019-01-04
知乎原文地址 作者:@狗屎咖啡
目前VS 和Clang都是支援utf-8的變數名、函式名,但 GCC不支援。
有人提意見,提了好幾年了:UTF-8 support for identifier names in GCC
GCC並沒有解決,但官方給了一個解決方案:FAQ - GCC Wiki
就是用這樣一條指令碼語句轉換一下原始檔
perl -pe 'BEGIN { binmode STDIN, ":utf8"; } s/(.)/ord($1) < 128 ? $1 : sprintf("\\U%08x", ord($1))/ge;'
這條語句的意思是將原始檔按utf-8讀取出來,大於128的unicode(不在ASCII裡)都用16進位制的\Uxxxxxxxx的格式替代。
這種格式叫UCN。
實際上gcc內部還是將UCN轉換成utf-8字串,再加到符號表。卻不支援原生的UTF-8符號,這個就有點搞笑了。
雖然有人會說,C、C++的標準裡沒有對UTF-8符號的支援,GCC不支援UTF-8符號是符合標準的。但是GCC從來就不是死守標準的乖寶寶對吧,加了不少擴充套件了。為啥這個不能擴充套件一下呢?
官方不加,咱可以同人一下嘛!
下面就告訴大家,怎麼在GCC里加UTF-8符號的支援。
在libcpp/lex.c 裡
1.加一個函式
bool is_utf8_char(cppchar_t c) { if (c > 0x80) return true; else return false; }
2.複製一份函式lex_identifier,命名為lex_utf8_identifier
if (! starts_ucn)
{
while (ISIDNUM (*cur))
{
hash = HT_HASHSTEP (hash, *cur);
cur++;
}
NORMALIZE_STATE_UPDATE_IDNUM (nst, *(cur - 1));
}
中ISIDNUM 改成 is_utf8_char:
if (! starts_ucn) { while (is_utf8_char (*cur)) { hash = HT_HASHSTEP (hash, *cur); cur++; } NORMALIZE_STATE_UPDATE_IDNUM (nst, *(cur - 1)); }
3.在函式 _cpp_lex_direct 中修改 switch 的 default
default:
create_literal (pfile, result, buffer->cur - 1, 1, CPP_OTHER);
break;
改為:
default:
if (is_utf8_char(c))
{
struct normalize_state nst = INITIAL_NORMALIZE_STATE;
result->type = CPP_NAME;
result->val.node.node = lex_utf8_identifier(pfile, buffer->cur - 1, false,
&nst, &result->val.node.spelling);
warn_about_normalization(pfile, result, &nst);
}
else
{
create_literal (pfile, result, buffer->cur - 1, 1, CPP_OTHER);
}
break;
OK!完工了。make bootstrap && make install 吧。
你就可以愉快地使用 UTF-8 變數,函數了。
成品:地址