68

我是发现我不能用作为 g++ 4.7 的有效标识符,即使-fextended-identifiers启用了该选项:

int main(int argc, const char* argv[])
{
  const char*  = "I'm very happy";
  return 0;
}

main.cpp:3:3: 错误:程序 main.cpp:3:3 中的杂散'\360':错误:程序
main.cpp:3:3 中的杂散'\237'
:错误:杂散'\230' in程序
main.cpp:3:3: 错误: 程序中出现杂散“\203”

经过一番谷歌搜索,我发现标识符中尚不支持 UTF-8 字符,但通用字符名称应该可以工作。所以我将我的来源转换为:

int main(int argc, const char* argv[])
{
  const char* \U0001F603 = "I'm very happy";
  return 0;
}

main.cpp:3:15:错误:通用字符 \U0001F603 在标识符中无效

所以显然不是一个有效的标识符字符。但是,该标准明确允许来自附件 E.1 范围内的字符,10000-1FFFD并且不允许将其作为 E.2 中的初始字符。

我的下一个努力是查看是否有任何其他允许的 Unicode 字符有效——但我尝试过的都没有。甚至连最重要的PILE OF POO ()字符都没有。

那么,为了有意义和描述性的变量名称,什么给出了?-fextended-identifiers做广告还是不做?它仅在最新版本中支持吗?其他编译器有什么样的支持?

4

3 回答 3

25

从 4.8 开始,gcc 不支持将 BMP 之外的字符用作标识符。这似乎是一个不必要的限制。此外,gcc 仅支持ucnid.tab中描述的一组非常有限的字符,基于 C 99和 C++ 98(它似乎尚未更新到 C11 和 C++11)。

如手册中所述,-fextended-identifiers是实验性的,因此它更有可能无法按预期工作。


编辑:

GCC从 4.9.0 开始支持 C11 字符集(准确地说是svn r204886)。所以OP的第二段代码使用\U0001F603确实有效。即使在https://gcc.godbolt.org-finput-charset=UTF-8上使用 GCC 8.2,我仍然无法获得用于工作的实际代码(您可能需要关注@DanielWolf提供的这个错误报告)。

同时,这两条代码都可以在 clang 3.3 上运行,除了-std=c++11.

于 2012-10-02T15:24:54.200 回答
14

这是 GCC 9 及之前版本中的一个已知错误。这在 GCC 10 中修复。

GCC 10的官方变更日志包含以下部分:

除了已经支持的 UCN 语法(\uNNNN或)之外,现在可以在输入编码(默认为 UTF-8)中直接指定标识符中的扩展字符:\UNNNNNNNN

static const int π = 3;
int get_naïve_pi() {
  return π;
}
于 2017-02-10T11:47:29.810 回答
6

但是,该标准在附件 E.1 中明确允许 10000-1FFFD 范围内的字符,并且在 E.2 中不允许将其作为初始字符。

要记住的一件事是,仅仅因为 C++ 标准允许(或不允许)某些功能,并不一定意味着您的编译器支持(或不支持)该功能。

于 2012-10-02T15:31:33.113 回答