【问题标题】:Is it possible to get GCC to compile UTF-8 with BOM source files?是否可以让 GCC 使用 BOM 源文件编译 UTF-8?
【发布时间】:2011-10-26 07:25:48
【问题描述】:

我在 Windows 上使用 Microsoft Visual Studio 和在 uBuntu Linux 上使用 GCC 开发 C++ 跨平台。

在 Visual Studio 中,我可以在我的代码中使用像“π”和“²”这样的 unicode 符号。 Visual Studio 始终将源文件保存为带有 BOM(字节顺序标记)的 UTF-8。

例如:

// A = π.r²
double π = 3.14;

只有在我先删除 BOM 时,GCC 才会愉快地编译这些文件。如果我不删除 BOM,我会收到如下错误:

wwga_hydutils.cpp:28:9: 错误:程序中出现杂散“\317”

wwga_hydutils.cpp:28:9: 错误:程序中出现杂散“\200”

这让我想到了这个问题:

有没有办法让 GCC 在不删除 BOM 的情况下编译 UTF-8 文件?


我正在使用:

  • Windows 7
  • Visual Studio 2010

和:

  • uBuntu Oneiric 11.10
  • GCC 4.6.1(由 apt-get install gcc 提供)

编辑:

正如第一位评论者所指出的,我的问题是不是 BOM,而是在字符串常量之外有非 ascii 字符。 GCC 不喜欢符号名称中的非 ascii 字符,但事实证明 GCC 与带有 BOM 的 UTF-8 完全兼容。

【问题讨论】:

  • 在 gcc 4.4.5 中对我来说很好,使用包含问题中两个 UNICODE 字符的字符串。带有 BOM 的文件。此外,您得到的错误与 BOM 无关,但似乎是有问题的 UNICODE 字符在任何字符串之外(这就是为什么它们被称为 stray。)
  • @JoachimPileborg 是的,unicode 字符在字符串之外,我使用的“π”作为符号名称,“²”只是在 cmets 中。当我删除 BOM 时,它确实消除了控制台输出中的错误,但我想这并不能保证 GCC 真的按照我的预期处理字符。
  • @JoachimPileborg,我已经更新了问题以包含我使用 unicode 字符的上下文。
  • double π = 3.14; : 排版 +1,数学 -1。
  • clang 在标识符中支持这些符号,gcc 仅在字符串中支持,要在 gcc 中的标识符中使用 Λ(希腊语 lambda)使用通用字符名称(ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/rzarg/…),所以函数 funΛ() 会写成 fun\u039B() 以便能够在 gcc 中运行。我将编译器更改为 clang,一切正常。 gcc 的-finput-charset=UTF-8 -fextended-identifiers 也无济于事。 -fextended-identifiers只是为了支持通用字符名格式,如果关闭(-fno-extended-identifiers)甚至fun\u039B()失败。

标签: gcc utf-8 g++ byte-order-mark


【解决方案1】:

根据GCC Wiki,尚不支持此功能。您可以使用 -fextended-identifiers 并预处理您的代码以将标识符转换为 UCN。从链接页面:

perl -pe 'BEGIN { binmode STDIN, ":utf8"; } s/(.)/ord($1) < 128 ? $1 : sprintf("\\U%08x", ord($1))/ge;' 

另见g++ unicode variable nameUnicode Identifiers and Source Code in C++11?

【讨论】:

    【解决方案2】:

    虽然 gcc 支持 unicode 标识符,但不支持 UTF-8 输入。因此,必须使用 \uXXXX 和 \UXXXXXXXX 转义码对 unicode 标识符进行编码。但是,如果还安装了支持 C99 转换的最新版本的 iconv,则 cpp 预处理器的简单单行补丁允许 gcc 和 g++ 处理 UTF-8 输入。详情见

    https://www.raspberrypi.org/forums/viewtopic.php?p=802657

    不过,补丁实在是太简单了,直接在这里就可以了。

    diff -cNr gcc-5.2.0/libcpp/charset.c gcc-5.2.0-ejo/libcpp/charset.c
    *** gcc-5.2.0/libcpp/charset.c  Mon Jan  5 04:33:28 2015
    --- gcc-5.2.0-ejo/libcpp/charset.c  Wed Aug 12 14:34:23 2015
    ***************
    *** 1711,1717 ****
        struct _cpp_strbuf to;
        unsigned char *buffer;
    
    !   input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset);
        if (input_cset.func == convert_no_conversion)
          {
            to.text = input;
    --- 1711,1717 ----
        struct _cpp_strbuf to;
        unsigned char *buffer;
    
    !   input_cset = init_iconv_desc (pfile, "C99", input_charset);
        if (input_cset.func == convert_no_conversion)
          {
            to.text = input;
    

    即使有补丁,也需要两个命令行选项来启用 UTF-8 输入。特别是,尝试类似

    $ /usr/local/gcc-5.2/bin/gcc \
        -finput-charset=UTF-8 -fextended-identifiers \
        -o circle circle.c
    

    【讨论】:

      猜你喜欢
      • 2016-05-03
      • 1970-01-01
      • 2012-06-01
      • 2023-03-14
      • 2018-05-21
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2015-11-11
      相关资源
      最近更新 更多