【问题标题】:Definition of an "expression" in the C and C++ standardsC 和 C++ 标准中“表达式”的定义
【发布时间】:2019-10-26 21:08:46
【问题描述】:

我问这个问题是因为我正在更新我的 C 和 C++ 课程资料,而且我有过去的学生问过这个问题......

来自 ISO/IEC 9899:2017 第 6.5 节表达式¶1(在 C++ 标准中类似):

表达式是一系列操作符和操作数,用于指定值的计算,或指定对象或函数,或产生副作用,或执行它们的组合。... "

因为标准编写者显然会仔细选择他们的词,所以使用“运算符和操作数的序列”这个短语似乎可能会误导我。这似乎表明要被视为一个表达式,必须有多个运算符和多个操作数。因此,像 123 这样的文字或像 XYZ 这样的变量不会被视为表达式,因为没有运算符,如果没有运算符,它们当然不能被视为操作数。

但是,如果 123 和 XYZ 实际上是表达式,那么将短语“运算符和操作数的序列”替换为“一个或多个字符的序列”或类似的东西不是更准确吗?

请告诉我我对标准的说明有什么误解。

【问题讨论】:

  • 虽然 C 和 C++ 在它们的规范中有一些相似的语法和有时相似的措辞,但它们仍然是不同的语言,规范中的差异会导致程序的语义差异很大。因此,在讨论这两种语言时请小心,因为看起来相似的内容可能根本不相似。
  • @Someprogrammerdude:这两个标准都使用了我所质疑的完全相同的短语。你能评论我的话题吗?
  • 您的陈述“似乎表明要被视为一个表达式,必须有多个运算符和多个操作数”对我来说似乎是错误的——一系列 foo 的长度可以是 1(在这种情况下只有一个 foo)或什至长度为 0(在这种情况下没有 foo)全部)-但是鉴于标准如何定义“操作数”,您的评论“如果没有运算符,它们当然不能被视为操作数”是一个很好的评论。这似乎是定义中的一个小错误。
  • 看看 6.5.1 主要表达式
  • @KeithThompson:好的——我不确定你要叫什么123,但它看起来很像一个操作数——尽管它没有应用任何运算符给它。我不想扩大讨论。我不认为这有帮助。如果您的“我不认为”评论是针对我的,那么您 100% 错误地引用了我所说的话,因此将我在这种情况下不会说的话放入我的嘴里。 (我看到我确实在我想要“或”的地方打错了“矿石”——哦,好吧)。

标签: c++ c expression language-lawyer standards


【解决方案1】:

和 C++ 标准中的类似

我不了解 C 标准,但 the C++ standard 将此声明置于 非规范 符号中。它对 C++ 没有规范价值,所以应该被理解为口语化。

【讨论】:

    【解决方案2】:

    您忘记了在 (6.5.1) 中具有单独定义的主要表达式。 您只是混淆了不同的实体;您提供的定义准确地描述了它应该描述的内容。

    6.5.1  Primary expressions
    Syntax:
       primary-expression:
         identifier
         constant
         string-literal
         (expression)
    

    【讨论】:

    • 是的,有一个primary-expression的语法定义。更相关的是,在 C11 6.5.17 中有一个 expression 的语法定义。但 6.5 第 1 段中的英语定义也是规范的,与语法不一致。在我看来,这是 C 标准中的一个缺陷(但不会导致任何实际问题)。
    【解决方案3】:

    是的,C 标准中“表达式”的定义是不完整的——但不会导致任何实际问题(除了像我这样挑剔的人)。

    您引用的文字中的“表达式”一词是斜体字,这意味着这是该术语的官方定义。从标准的其他部分可以清楚地看出,例如,123 是一个表达式:它是一个 decimal-constant,它是一个 integer-constant,它是一个constant,这是一个primary-expression`,这是一个postfix-expression,它(跳过多个步骤)是一个表达式.

    不是“一系列运算符和操作数”。没有操作符,这意味着123 不是操作数(这可以通过参考标准中其他地方的operatoroperand 的定义来证明)。

    在实践中,我从未听说任何人,无论是编译器实现者还是 C 程序员,都因为这个不完整的定义而遇到任何真正的困难。编译器实现者参考语言语法。 C 程序员在阅读标准之前可能对什么是“表达式”有一个很好的了解。

    我希望看到 表达式 的定义在新版本的标准中得到更新。恕我直言,引用语法而不是尝试英文描述的定义将是一种改进。

    但如果不更新,我们都会继续使用表达式,没有任何问题。

    至于 C++,Nicol Bolas's answer 正确指出 C++ 标准没有像 C 标准那样的“表达式”的正式定义。它在第 8 条的顶部确实有类似的措辞:“表达式是 指定计算的运算符和操作数的序列。”——但是“表达式”这个词不是斜体,并且该句子是“注释”的一部分,因此是非规范性的。在 C++ 中,标准在语法上定义表达式。

    【讨论】:

    • 本标准有意义的唯一方法是希望读者填补空白。修正标准以消除差距可能是一件好事,但有足够的差距需要大修,如果标准不这样做,最好让它明确承认它的不完整性。
    • 编译器编写者仅在他们或委员会不清楚的情况下才使用标准。当事情看起来很清楚时,std 文本会被忽略(考虑到其糟糕的质量水平,最好忽略)。
    • @curiousguy:除了标准之外,编译器作者还指的是什么?
    • @KeithThompson 奇怪的问题。他们指的是什么?为什么他们只关注标准?
    • @curiousguy 因为标准定义了语言。例如,对于 C,如果标准说一件事而 K&R 说另一件事,我希望任何编译器实现者都遵循该标准。我不同意标准的质量。不完美,但总体来说还不错。
    猜你喜欢
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2018-03-28
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多