【问题标题】:In the C++ standard, what is specified to occur when a "shall" requirement is violated?在 C++ 标准中,当违反“应”要求时,会发生什么规定?
【发布时间】:2014-08-14 05:06:25
【问题描述】:

例如,名言(§3.2/1)

任何翻译单元都不得包含一个以上的任何变量、函数、类类型、枚举的定义 类型或模板。

我认为除非另有说明,否则我认为“应”要求应被解释为隐含地遵循“否则程序格式错误”。然而,其他人声称“应该”的意思是“否则行为未定义”。

在我遇到的每一种标准中,“应”要求没有遵循“否则行为未定义”或“不需要诊断”之类的标准,它发生的规则是显然是可诊断的,并且由我所知道的所有编译器诊断(上面的段落是一个例子)。这就是为什么我认为它的意思是“否则程序格式错误”,,需要进行诊断。

无论如何,这些只是我的想法。我会很感激一个权威的答案。

【问题讨论】:

  • 本文来自The One Definition Rule,属于特例!请参阅 [defns.well.formed],它表示任何违反 ODR 中“应”的行为都意味着程序格式错误。

标签: c++ language-lawyer


【解决方案1】:

是的,要形成良好的格式,程序必须遵循您在问题中引用的单一定义规则(第 1.3.26 节):

格式良好的程序

根据语法规则、可诊断语义规则和单一定义规则 (3.2) 构造的 C++ 程序。

其他可诊断规则指定为(§1.4):

1.4 实施合规性 [intro.compliance]

1 可诊断规则集由本国际标准中的所有句法和语义规则组成,除了 对于那些包含“不需要诊断”或被描述为导致“未定义行为”的明确表示法的规则。
2 尽管本国际标准仅规定了对 C++ 实现的要求,但如果将这些要求表述为对程序、程序部分或程序执行的要求,则通常更容易理解。此类要求具有以下含义:
— 如果程序不违反本国际标准中的规则,则符合要求的实现应在其资源限制内接受并正确执行2该程序。
如果程序包含违反任何可诊断规则的行为,或者当实现不支持该构造时,本标准中描述为“有条件支持”的构造发生,符合要求的实现应发出至少一条诊断消息。
— 如果一个程序违反了不需要诊断的规则,则本国际标准对该程序的实现没有任何要求。
[强调添加]

是的,如第二个要点所述,如果违反了可诊断规则,则需要进行诊断。

【讨论】:

  • 好吧,让我看看我是否理解正确:“Shall”没有特殊含义;这只是某些规则中使用的语言。如果一个程序违反了 any 规则,那么它就是格式错误的,除非它明确表示“未定义的行为”。如果程序格式错误,则实现必须发出诊断,除非规则明确表示“不需要诊断”。
  • @Brian:不完全是。在这方面,它没有区分“未定义的行为”和“不需要诊断”。因此,除非它说明了这两件事之一,否则违反规则需要进行诊断。对于它的价值,C 标准更明确地要求“应”使规则符合要求。 Pete Becker(当时是 C++ 标准的编辑)也提出了同样的建议,但他显然不喜欢将可诊断规则限制为包含“shall”或“shall not”的规则。我不能责怪他——在某些情况下,这会导致措辞非常生硬。
  • 我不是以英语为母语的人,但用“must”代替“shall”会不会更清楚?
  • @Claptrap 我的回答中引用的表 H.1 的脚注指出:“不要使用“必须”作为“应”的替代。(这将避免文件要求之间的任何混淆和外部法定义务。)”
【解决方案2】:

除了@JerryCoffin 的回答,还有ISO/IEC Directives Part 2(管理所有 ISO/IEC 文档,包括 C++ 标准),特别是附件 H 表达的语言形式条文

应使用表 H.1 中所示的语言形式来表示 要求严格遵守,以符合 不允许偏离的文件。

  • 是,
  • 需要,
  • 要求,
  • 必须,
  • 只允许……,
  • 这是必要的

不得

  • 不允许[允许][可接受][允许],
  • 必须不是
  • 要求……不是
  • 不应该

因此,违反“shall”要求会使程序格式错误。诊断问题已在别处得到解答。

【讨论】:

  • @hvd 已修复,我遇到了一些连接问题
  • 啊,这就解释了。 :) 我认为这表明违反“应”要求的程序不符合 C++ 标准,但这并不表明这样的程序格式错误:它同样可能是未定义的,不是吗?
  • @hvd 我不确定,但我认为“未定义的行为”是“格式错误”的子集。请参阅[defns.undefined]:“许多错误的程序构造不会产生未定义的行为;它们需要被诊断出来。”如果您能找到一个要求,即错误使用时意味着未定义的行为,那将会很有趣。
  • 好吧,除非明确不需要诊断,否则格式错误需要诊断,未定义的行为隐式不需要诊断,因此后者不能是前者的子集。不需要诊断的具体“应”要求是 17.6.2.2p3:“翻译单元应仅在任何外部声明或定义之外包含标头,并且应在该翻译单元中的第一个引用之前在词法上包含标头以该标头中声明的任何实体。”诊断是不合理的:[...]
  • [...] 这样的诊断将禁止标头保护,因为该规则甚至禁止 #include <standard header> / void f() { / #include <standard header> / },并且几乎所有的实现都会使第二个包含绝对没有效果。
猜你喜欢
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 2018-12-18
  • 2011-01-01
  • 1970-01-01
  • 2012-06-24
相关资源
最近更新 更多