2017-11-24 如何使GCC支持中文(utf-8)的變量名、函數名?


知乎原文地址 作者:@狗屎咖啡

目前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 變量,函數了。

成品:地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM