我偶然发现了一些像这样的 C++ 代码:
int $T$S;
首先,我认为这是某种 PHP 代码或错误粘贴在那里的东西,但它编译和运行良好(在 MSVC 2008 上)。
什么样的字符对 C++ 中的变量有效,还有其他奇怪的字符可以使用吗?
我偶然发现了一些像这样的 C++ 代码:
int $T$S;
首先,我认为这是某种 PHP 代码或错误粘贴在那里的东西,但它编译和运行良好(在 MSVC 2008 上)。
什么样的字符对 C++ 中的变量有效,还有其他奇怪的字符可以使用吗?
根据标准,唯一合法的字符是字母数字和下划线。该标准确实要求 Unicode 认为的任何字母都是可接受的(但仅作为单个代码点字符)。在实践中,实现提供了扩展(即有些接受 $)和限制(大多数不接受所有必需的 Unicode 字符)。如果您希望代码可移植,请将符号限制为 26 个无重音字母、大写或小写、十位数字和“_”。
它是一些编译器的扩展,而不是 C 标准
微软特定
只有 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
据我所知,只有字母(大写和小写)、数字(0
to 9
)和_
根据标准对变量名有效(注意:变量名不应以数字开头)。
所有其他字符都应该是编译器扩展。
这不是好的做法。通常,您只能在标识符 ( [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++ 不将 $ 之类的字符视为特殊字符,因此它的处理方式与句点等其他字符不同。