30

我偶然发现了一些像这样的 C++ 代码:

int $T$S;

首先,我认为这是某种 PHP 代码或错误粘贴在那里的东西,但它编译和运行良好(在 MSVC 2008 上)。

什么样的字符对 C++ 中的变量有效,还有其他奇怪的字符可以使用吗?

4

4 回答 4

33

根据标准,唯一合法的字符是字母数字和下划线。该标准确实要求 Unicode 认为的任何字母都是可接受的(但仅作为单个代码点字符)。在实践中,实现提供了扩展(即有些接受 $)和限制(大多数不接受所有必需的 Unicode 字符)。如果您希望代码可移植,请将符号限制为 26 个无重音字母、大写或小写、十位数字和“_”。

于 2011-10-28T07:48:03.513 回答
14

它是一些编译器的扩展,而不是 C 标准

MSVC:

微软特定

只有 Microsoft C++ 标识符的前 2048 个字符是重要的。用户定义类型的名称由编译器“修饰”以保留类型信息。结果名称(包括类型信息)不能超过 2048 个字符。(有关详细信息,请参阅装饰名称。)可能影响装饰标识符长度的因素有:

  • 标识符是表示用户定义类型的对象还是从用户定义类型派生的类型。
  • 标识符是表示函数还是从函数派生的类型。
  • 函数的参数数量。

美元符号也是 Visual C++ 中的有效标识符。

// dollar_sign_identifier.cpp
struct $Y1$ {
    void $Test$() {}
};

int main() {
    $Y1$ $x$;
    $x$.$Test$();
}

https://web.archive.org/web/20100216114436/http://msdn.microsoft.com/en-us/library/565w213d.aspx

最新版本:https ://docs.microsoft.com/en-us/cpp/cpp/identifiers-cpp?redirectedfrom=MSDN&view=vs-2019

海合会:

6.42 标识符名称中的美元符号

在 GNU C 中,您通常可以在标识符名称中使用美元符号。这是因为许多传统的 C 实现允许这样的标识符。但是,一些目标机器不支持标识符中的美元符号,通常是因为目标汇编器不允许它们。

http://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs

于 2013-08-03T14:39:28.510 回答
2

据我所知,只有字母(大写和小写)、数字0to 9)和_根据标准对变量名有效(注意:变量名不应以数字开头)。

所有其他字符都应该是编译器扩展。

于 2011-10-28T07:48:22.843 回答
0

这不是好的做法。通常,您只能在标识符 ( [a-z][A-Z][0-9]_) 中使用字母数字字符和下划线。

表面水平

与其他语言(bash、perl)不同,C 不使用$来表示变量的使用。因此,它在技术上是有效的。在 C 中,它很可能属于 C11, 6.4.2。这意味着现代编译器似乎确实支持它。

至于你的 C++ 问题,让我们测试一下!

int main(void) {
    int $ = 0;
    return $;
}

在 GCC/G++/Clang/Clang++ 上,这确实可以编译,并且运行良好。

更深层次

编译器获取源代码,将其转换为令牌流,将其放入抽象语法树 (AST),然后使用它生成代码(例如汇编/LLVM IR)。您的问题实际上只围绕第一部分(例如词法分析)。

C/C++ 的语法(因此词法分析器实现)不被$视为特殊的,不像逗号、句号、细箭头等......因此,您可以从下面的 c 代码中获得像这样的词法分析器的输出:

int i_love_$ = 0;

在词法分析器之后,这变成了这样的令牌流:

["int", "i_love_$", "=", "0"]

如果您在哪里获取此代码:

int i_love_$,_and_.s = 0;

词法分析器将输出一个令牌流,如:

["int", "i_love_$", ",", "_and_", ".", "s", "=", "0"]

如您所见,由于 C/C++ 不将 $ 之类的字符视为特殊字符,因此它的处理方式与句点等其他字符不同。

于 2021-07-15T03:51:40.623 回答