【问题标题】:Is promotion to int required by the C++ standard?C++ 标准是否需要提升为 int ?
【发布时间】:2014-05-13 15:17:39
【问题描述】:

获取以下代码片段。

short int a, b = 30001, c = 30002, d = 30003;
a = b + c - d;

假设 short int 是 16 位,int 是 32 位。这是 C++ 中未定义的行为吗?

我对 C 标准的解读是 b 和 c 都必须提升为 int,因此整个计算必须使用 int 算术执行。最终值适合short,所以不会出现UB。

我在 C++ 标准中找不到对应的语言。整数提升部分 (n3797 S4.5/1) 说:

除 bool、char16_t、char32_t 或 wchar_t 之外的整数类型的纯右值,其整数转换 rank (4.13) 小于 int 可以转换为 int 类型的纯右值,如果 int 可以表示源类型的所有值;否则,源纯右值可以转换为无符号整数类型的纯右值。

重点是我的。 可以必须不同。

S 5/10 说:

许多期望算术或枚举类型的操作数的二元运算符会导致转换并以类似的方式产生结果类型。目的是产生一个通用类型,这也是结果的类型。这种模式称为通常的算术转换,定义如下:

...

— 否则,应在两个操作数上执行整数提升 (4.5)。那么以下 规则应应用于提升的操作数:

——如果两个操作数的类型相同,则不需要进一步转换。

如果值没有提升那么后果就是计算的中间值超出了short int的范围,也就是说答案应该是肯定的,这是UB。

这也意味着 C 和 C++ 之间不太可能存在差异。兼容性部分未提及。

我能找到的所有其他问题都涉及类型的混合,有符号/无符号等。这个问题没有什么特别的。它出现在我对this 的回答中。

有接受者吗?

【问题讨论】:

  • 您在 5/10 的报价使用。这不是可选的。
  • 此外,结果不必适合short。 4.7 说“如果目标类型是有符号的,如果它可以在目标类型(和位域宽度)中表示,则该值不变;否则,该值是实现定义的。”。 实现定义的值未定义的行为非常不同。
  • @BenVoigt:就这些吗?一次提到应该是? C 标准对此非常明确,但 C++ 甚至没有为此提供脚注。脚注 62 涵盖了一些其他类型,但不包括 char 或 short。
  • @BenVoigt:再次让我感到惊讶。如果中间结果超出范围,则为 UB,但如果最终值超出范围,则不是 UB。
  • @davidpfx:它与中间值或最终值无关。类型之间的精度损失转换是安全的,但执行溢出的算术运算则不是。

标签: c++ language-lawyer


【解决方案1】:

在 4/5 的下方是:

这些转化称为整体促销

因此,当 5/10 说“应进行整体促销”时,这意味着需要列出的任何一个转化匹配(只有一个匹配)(在这种情况下)。

“可以”措辞保证这些转换是可能的,并且不排除支持其他转换,包括身份转换。但没有其他转换带有整体提升的名称。

【讨论】:

  • 是还是不是UB?
  • @bolov:不,这里没有未定义的行为。操作数提升为int,所有值和中间值都适合int
猜你喜欢
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多