代码之家  ›  专栏  ›  技术社区  ›  Lundin

“留作任何用途”是什么意思?

  •  50
  • Lundin  · 技术社区  · 6 年前

    注意:这是一个 如果某些C++专家可以提供一个理由或历史原因C++为什么使用不同的措辞比C。


    • 总是留作任何用途 .
    • 所有以下划线开头的标识符始终保留为在普通和标记名空间中用作具有文件范围的标识符。

    “留作任何用途”不是指留作任何用途吗 除了C语言本身的未来扩展?意味着实现是

    而上面的第二个短语,关于单个的引导下划线似乎是针对实现的?

    一般来说,C标准的编写方式期望编译器供应商/库实现者是典型的读者,而不是应用程序程序员。

    值得注意的是,C++有一个非常不同的措辞:

    • 包含双下划线的每个名称( __ )或以下划线开头,后跟大写字母(2.11) 保留给实现以供任何使用 .

    (见 What are the rules about using an underscore in a C++ identifier? )

    6 回复  |  直到 6 年前
        1
  •  33
  •   Baum mit Augen    6 年前

    在C标准中,术语“保留”的含义由7.1.3p2定义,紧靠您引用的项目符号列表下方:

    不保留其他标识符。如果

    重点:保留标识符对 程序 ,而不是实现。因此,公共解释(保留标识符可由实现用于任何目的)对于C是正确的。

        2
  •  16
  •   Sneftel    6 年前

    作为 一种描述是什么使一个程序形成良好的结构,以及它的效果是什么。那是因为 一个符合标准的编译器是一个为任何符合标准的程序做正确事情的编译器:

    严格一致的程序只能使用语言和库的那些特性

    极大地 编译器的限制性扩展。例如,仅基于该子句,编译器不应该定义 它自己的保留字。毕竟,任何一个特定的编译器给定的单词 希望 然而,要保留,可能会出现在严格一致的程序中,迫使编译器手动执行。

    然而,标准仍在继续:

    一致性实现可以有扩展(包括附加的 库函数),前提是它们不会改变任何严格符合 程序。

    这是关键。编译器扩展的编写方式必须使其影响 不合格 程序(包含未定义行为的程序,或者根本不应该编译的程序),允许它们编译并执行有趣的额外操作。

    需要 这些标识符是为了给实现提供一些额外的回旋余地,因为它们提供了一些使程序不一致的东西。编译器之所以能够识别, __declspec 在声明中的任何部分都是非法的,所以编译器可以做任何它想做的事情!

    因此,“为任何用途保留”的重要性在于,编译器有权将这些标识符视为具有它所关心的任何含义。未来的兼容性是一个相对遥远的问题。

    一致性实现可以具有扩展(包括附加的库函数),前提是它们具有扩展 不会改变任何格式良好的程序的行为。需要实现来诊断 根据本国际标准,使用格式错误的扩展名。 然而,既然这样做了,

    我怀疑措辞的差别在于C++标准,只是对扩展如何工作更清楚。尽管如此,C标准中的任何内容都不能阻止实现做同样的事情(我们基本上都忽略了编译器在每次使用 .)

        3
  •  14
  •   Lundin    6 年前

    关于C和C++的措辞差异,我将自己的小研究发布在这里作为参考:

    • K&R C 1st edition 有以下文字:

    • K&R第二版增加了附录B,其中提到了标准库,在这里我们可以阅读

      以下划线开头的外部标识符是为库保留的,所有这些标识符都是这样 以下划线和大写字母或其他下划线开头的其他标识符。

    • 早期的ANSI C草案以及“C90”ISO 9899:1990与当前的ISO标准中的文本相同。

    • 然而,最早的C++草稿有不同的文本,如@ HVD所指出的,可能是C标准的澄清。从 DRAFT: 20 September 1994 :

      17.3.3.1.2全局名称
      ...
      保留给实现以供任何使用

    显然,“保留任何用途”的措辞是由ANSI/ISOC90委员会发明的,而C++委员会几年后使用了一种更清晰的措辞,类似于标准前K&中的措辞。一本书。


    C99基本原理V5.10在7.1.3中说明了这一点:

    以下划线开头,后跟大写字母或下划线的所有其他标识符。 图书馆要做好自己的工作,就必须发挥作用。

    这使委员会的意图非常明确:“保留供任何使用”是指“保留给实施者”。


    同样值得注意的是,现行C标准在6.2.5中的其他地方有以下规范性文本:

    实现定义的扩展有符号整数类型。38)

    资料性的脚注38中写道:

    38)实现定义的关键字应具有标识符的形式,保留用于以下任何用途:

        4
  •  4
  •   David Hammen    6 年前

    C有多个上下文,其中一个符号可以有一个定义:

    • 宏名称的空格,
    • 宏参数的形式名称空间(该空间特定于每个函数,如宏),
    • 标签的空间(该空间特定于每个函数),以及

    什么“保留供任何使用”意味着兼容程序中的用户代码不能使用 1 可以

    “为任何用途保留”并不意味着实现不能使用这些符号。保留的目的是提供实现可以自由使用的名称空间,而不用担心实现定义的名称与兼容程序中用户代码定义的名称冲突。


    1 该标准并不完全意味着“不能使用”。该标准鼓励编程使用少量以双下划线开头的名称。例如,需要一个兼容的实现来定义 __STDC_VERSION__ , __FILE__ __LINE__ ,和 __func__ __功能__ .

        5
  •  2
  •   supercat    6 年前

    C标准允许实现将他们认为合适的任何含义附加到保留标识符上。当没有理由这样做时,大多数实现将保留形式的未识别标识符视为与任何其他已识别标识符相同,从而允许如下操作:

    #ifdef __ACME_COMPILER
    #define near __near
    #else
    #define near
    #endif
    
    int near foo;
    

    声明标识符 foo 使用 __near 如果代码是在Acme编译器中处理的(它可能会支持这样的东西),那么限定符也可以与其他编译器兼容,这些编译器不需要使用这样的指令或从中受益。没有什么能阻止一致性实现定义 __ACME_COMPILER 和口译 意思是“发射核导弹”,但一个高质量的实现不应该破坏上面的代码。如果一个实现不知道 这意味着,将其视为任何其他未知标识符将允许它支持上述有用的构造。

        6
  •  0
  •   thb    6 年前

    你的问题可以从相反的方向看。该标准允许实现(正如您所观察到的)使用类似 _Foo foo . 后者是为 使用。

    为了便于讨论,我们假设未来的C标准引入了新的关键字 _福 . 假设的实现已经在使用这个符号,那么会发生什么呢?

    回答:

    1. 稍后, 作为实施新标准的一部分, 实现会悄然改变 _福 _Bar .

    没问题。