【问题标题】:dollar sign in variable name?变量名中的美元符号?
【发布时间】:2011-12-17 02:30:17
【问题描述】:

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

int $T$S;

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

哪些字符对 C++ 中的变量有效?还有其他奇怪的字符可以使用吗?

【问题讨论】:

  • “可以”!=“应该”。在变量名中使用 $ 是该语言的扩展,可能不适用于其他编译器(可能 GCC 除外,它对每个语言扩展都有一个标志)。
  • 我什至会说它使用奇怪的字符堵塞了变量名,所以不,我不想使用它,只是想知道它:-)
  • 在标识符中使用$ 在VMS 上相当普遍,其中许多系统库例程的名称类似于SYS$SOMETHING。 g++ 支持将其作为扩展,但如果您指定 -pedantic,则会发出警告。
  • @KeithThompson:至于现在 2015-11-17 gcc 4.9.3 甚至没有使用 -pedantic 开关发出警告。在此期间会有所改变吗?
  • @AlBundy:C 标准允许在标识符中使用“其他实现定义的字符”。即使使用-pedantic,也不需要警告(尽管我个人希望有一种简单的方法来警告此类事情,而无需为每个功能指定单独的选项)。

标签: c++ variables visual-c++ identifier variable-names


【解决方案1】:

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

【讨论】:

  • 如果您引用支持您答案的标准的特定部分,这将是一个更好的答案。
  • @Caleb 它在明显的地方:§2.11 标识符。
【解决方案2】:

它是一些编译器的扩展,而不是 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

【讨论】:

  • 它不是only在微软的编译器中有效。 G++ 也支持它作为扩展。但是,是的,它是特定于编译器的,而不是标准的一部分。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    这不是一个好习惯。通常,您只能在标识符中使用字母数字字符和下划线 ([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++ 不会将 $ 之类的字符视为特殊字符,因此它的处理方式与句点等其他字符不同。

    【讨论】:

    猜你喜欢
    • 2012-07-31
    • 2012-09-05
    • 1970-01-01
    • 2011-03-29
    • 2015-12-31
    • 2012-04-17
    相关资源
    最近更新 更多