C标识符名称:哪个编译器附带什么?

时间:2019-01-30 20:40:56

标签: c compilation

我在externextern "C"上进行了一些试验,偶然地在其中一个标识符上出现了错字-$被偷了。当我编译代码并得到一个未定义符号的错误,最终看到了导致它的原因,这使我产生了好奇,如果它真的可以编译。猜猜是什么-actually实际上是 did 进行编译的。

根据我之前阅读的文档,标识符规则基本上是:

  • 开头没有双下划线-因为这些都是保留的。
  • 没有下划线和大写字母-也保留。
  • 必须以字母和非数字开头。
  • 不得超过31个字符。
  • 可以包含a-zA-Z0-9_

但是这个编译的很好-也没有警告显示:

void __this$is$a$mess() {}
int main() { __this$is$a$mess(); }

观看时:

Ingwie@Ingwies-Macbook-Pro.local /tmp $ clang y.c
Ingwie@Ingwies-Macbook-Pro.local /tmp $ nm a.out
0000000100000f90 T ___this$is$a$mess
0000000100000000 T __mh_execute_header
0000000100000fa0 T _main
                 U dyld_stub_binder

我可以很清楚地看到符号名称。

那么,为什么按照Clang的要求我可以做到这一点,尽管按照ANSI标准,它不应该这样做?甚至我安装的GCC 6都没有警告或错误。

哪种编译器将允许使用哪种类型的标识符-为什么呢?

2 个答案:

答案 0 :(得分:6)

2018 C标准中的标识符规则包括:

  • 按照6.4.2.1的规定,标识符是一个 identifier-nondigit digit 字符的序列,以一个 identifier开头-nondigit
  • 一个 identifier-nodigit _azAZ,是一个通用的-字符名称,或“其他实现定义的字符”。
  • 数字09
  • 通用字符名称\u,后接四个十六进制数字,或者为\U,后接八个十六进制数字,指定https://github.com/aframevr/aframe/blob/master/src/components/cursor.js#L213字符。
  • li>

因此,如果实现允许$,则这是该实现的有效字符。您可以使用它,但是它可能无法移植到其他实现中。 C标准要求实现以接受列出的特定字符,但允许允许它们接受更多字符。通常,应将C标准视为一个开放的区域,而不是一个围墙花园:行为是在该区域内定义的,但是您不能在障碍处停下来。您可能会自行承担风险,承担责任。

您所教的规则是有关可移植内容的规则,而不是C标准要求实现以限制您使用的内容的规则。

C标准定义了严格符合规范的代码(大致上讲,该代码应在任何C实现中都适用)和 conforming code (其适用于任何C实现中的代码)至少一个C实现。合格代码仍然是C代码。因此,您所教的规则是严格遵守代码的。

通常,您应该更喜欢编写严格合规的代码,并且仅在受益(速度,在特定平台上的开发简便性,无论如何)值得(损失可移植性)时才使用其他功能。

答案 1 :(得分:5)

  

根据我之前阅读的文档,   标识符基本上是:

     
      
  • 开头没有双下划线-因为这些都是保留的。
  •   
  • 没有下划线和大写字母-也保留。
  •   

此类标识符确实是保留的,但这意味着不能声明或定义它们,不是它们不能成为标识符,或者它们不一定有意义。

  
      
  • 必须以字母和非数字开头。
  •   

字母确实是非数字,但并非所有非数字都是字母。 _字符是一个很好的例子。

  
      
  • 不得超过31个字符。
  •   

这不是语言的正式限制。 C要求实现在外部标识符中至少支持31个重要个字符。不能保证仅在32 nd 字符或更高版本上不同的两个外部标识符被识别为不同的,但是它们不会成为标识符。此外,实现必须在内部标识符中识别出至少63个有效字符,而且这些标识符可能更长。

某些实现可以识别更重要的字符,甚至可以识别无穷大的数字。

  
      
  • 可能包含a-z,A-Z或0-9和_。
  •   

是的,但也可以明确地 包含其他实现定义的字符。特别是$字符是相当普遍允许的字符。

  

那么为什么Clang让我这样做,尽管是通过ANSI   标准,应该不?我安装的GCC 6都没有发出警告   或与此有关的错误。

该标准绝不表示不允许包含$字符的标识符。它明确允许实现接受该字符以及标识符中的几乎任何其他字符,尽管有些不能务实地被接受,因为允许它们会引起歧义。使用包含此类字符的标识符的程序不会因此而失败,而接受包含它们的实现也不会因此而因此而失败。这样的程序确实不能严格遵守,但是,该术语是由标准定义的。