【问题标题】:undefined behaviour and C++ language stability未定义的行为和 C++ 语言稳定性
【发布时间】:2021-01-21 10:19:42
【问题描述】:

我是told 认为#defining 语言关键字是未定义的行为。这与以下事实有何关系:

  1. 用户可以#define代码中不是关键字的名称。
  2. 随着时间的推移,该语言可以获得以前不是关键字的新关键字。
  3. 如果用户使用的任何构造不再受支持,用户应该能够使用新编译器编译旧代码并获得编译时诊断而不是未定义的行为。

#3 显然是我的假设,但我认为这个假设很重要,因为较新的编译器往往更好,并且“了解现行法律的全部范围”是一个理论上的法律假设,不适用于软件开发人员,我希望(如果编译器假设否则,它可以用它喜欢的任何未定义行为替换代码中的任何编译时错误)。

【问题讨论】:

  • 您链接到的问题已被删除,因此无济于事。我们中的许多人看不到它。
  • @anastaciu:不是每个人都有超过 10k 的代表。再说一遍,没有帮助。
  • 您链接到的评论并没有比您在问题中所说的更多。只需将其删除。
  • 你不需要走到这个 UB 案例中:一个新的、冲突的关键字通常会导致语法错误。这就是为什么 C++ 的新关键字有点牵强(constexprconstevalco_await、总有一天reflexpr...)
  • TBH,我想知道为什么 3. 不成立。如果遇到#define <keyword>,编译器会报告警告应该是一个非常简单的功能。

标签: c++


【解决方案1】:

#3 并非如此,并且从未得到任何人的保证。虽然 C++ 委员会不喜欢创建不会破坏的向后不兼容性,但他们有时还是会这样做。

你不应该期待没有被告知期待的事情。

是的,对于#defined 该关键字的人来说,添加新关键字可能会静默中断。这是用户被告知在他们的#define 名称中使用 ALL_CAPS 的众多原因之一,因为关键字几乎肯定不会出现在 ALL_CAPS 中。

【讨论】:

  • 当您使用带有关键字的 #define 时,编译器当然可以识别,所以问题是为什么标准不需要对这种情况进行诊断?
  • @MarkRansom:这不是 OP 实际提出的问题。
  • @MarkRansom:引用 Raymond Chen 的话,“因为该功能从 -100 点开始”。由于已经建议避免使用宏,并且如果您确实需要宏,还有一个额外的建议使用大写,因此该诊断的好处根本不会超过 not 的默认位置诊断。此外,从标准化实践的角度来看,现有的实现并没有这样做,用户也没有要求这样做。
  • @MarkRansom:这是关于 OP 期望但不应该的期望,因为任何人都无法保证。这是我回答的重点。
  • 我的评论的重点是,尽管@MSalters 提出了观点,但标准没有充分的理由不要求它。
【解决方案2】:

C++ 标准并不完全向后兼容。这并不妨碍您使用现代编译器。

如果你想用新的编译器编译旧代码,你可以用一个标志明确地设置 C++ 版本。例如,对于 GCC,默认的 C++ 版本随版本而变化。要明确设置它,请使用 -std 选项,例如std=c++11std=c++0x

那么在此版本之后引入的任何关键字都不会生效,因此您不会遇到未定义的行为。另一方面,如果您想使用较新的语言功能,则需要仔细阅读文档中的新引入关键字和一些更改的细微之处,并相应地查看您的代码。

【讨论】:

  • 也许:一旦你坚持一个标准,标准上的任何变化都是无关紧要的,你并没有完全回答这个问题
  • @idclev463035818 我不明白。标准显然没有改变,但添加关键字时编写了新版本的标准。
  • 问题是关于针对标准 X 编写和编译的代码以及使用 X+1 编译相同代码时会发生什么。你只是说“留在X”。 (不是我的投票)
  • 是的,我只是说 C++ 标准并不完全向后兼容。这是一个众所周知的事实,也是问题的答案。是的,我知道这不是您的投票,并感谢您的解释。
【解决方案3】:

#3 如果用户使用的任何构造不再受支持,用户应该能够使用新编译器编译旧代码并获得编译时诊断而不是未定义的行为。

这是一件值得努力的好事情,但技术上没有这样的保证。

#2随着时间的推移,该语言可以获取以前不是关键字的新关键字。

是的。由于希望保持现有程序正常运行,标准委员会通常反对引入新关键字,但无论如何都会发生。

对于引入新关键字的情况,有一个技巧可以避免与您的宏发生名称冲突(很有可能):使用大写。除了_Pragma 之外,没有任何 C++ 关键字使用大写字母,而且这很可能在未来保持不变。对于除宏之外的其他标识符,使用关键字会使程序格式错误,因此可以保证进行诊断。

【讨论】:

    猜你喜欢
    • 2021-10-21
    • 2011-11-06
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多