如何使GCC支持中文(utf-8)的变量名、函数名?

简介: 通过修改gcc编译器源码, 使之支持中文变量名, 函数名. Allow gcc to support unicode identifiers.

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

目前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 变量,函数了。

成品:地址

2017-11-24

相关文章
|
NoSQL 编译器 开发工具
006.gcc编译器
gcc是什么?
378 0
006.gcc编译器
|
编译器 Linux 开发工具
|
存储 NoSQL 算法
从一个crash问题展开,探索gcc编译优化细节
问题分析的过程也正是技术成长之路,本文以一个gcc编译优化引发的crash为切入点,逐步展开对编译器优化细节的探索之路,在分析过程中打开了新世界的大门……
|
前端开发 C语言
gcc动态库升级
gcc动态库升级
1417 1
|
存储 编译器 C语言
深入理解GCC 和 G++ 编译器
GCC 和 G++ 是 GNU 工具链中的核心编译器,支持 C 和 C++ 程序开发。本文详细介绍其编译流程、常用选项及动态链接与静态链接的区别。编译过程分为预处理、编译、汇编和链接四个阶段,每个阶段有特定任务和命令选项。常用选项如 `-E`、`-S`、`-c` 和 `-o` 分别用于预处理、生成汇编代码、生成目标文件和指定输出文件。动态链接节省空间且易于更新,但依赖运行时库;静态链接独立高效,但文件较大且更新困难。合理选择优化选项(如 `-O0` 至 `-O3`)可提升程序性能。掌握这些知识有助于开发者更高效地编写、调试和优化代码。
深入理解GCC 和 G++ 编译器
|
编译器 Linux C语言
gcc的编译过程
GCC(GNU Compiler Collection)的编译过程主要包括四个阶段:预处理、编译、汇编和链接。预处理展开宏定义,编译将代码转换为汇编语言,汇编生成目标文件,链接将目标文件与库文件合并成可执行文件。
793 11
|
编译器 开发工具 C语言
Gcc 链接文件
Gcc 链接文件
535 4
|
C语言
gcc的简易用法
【5月更文挑战第10天】gcc的简易用法。
368 8
|
C语言
gcc的简易用法(编译、参数与链接)
【5月更文挑战第14天】gcc的简易用法(编译、参数与链接)。
423 1
|
Unix Java 编译器
安装gcc
【5月更文挑战第14天】安装gcc。
791 1