C ++ 20的分支需要二进制补码

Adr*_*thy 10 c++ undefined-behavior twos-complement c++20

C ++ 20将指定带符号整数类型必须使用二进制补码。鉴于(实际上?)每个实现当前都使用二进制补码,这似乎不是一个很大的变化。

但是我想知道这种改变是否会将某些“未定义的行为”转变为“实现定义”甚至“定义”。

考虑绝对值函数std::abs(int)及其一些重载。C ++标准通过引用C标准来包括此功能,该标准表示如果无法表示结果,则行为未定义。

用二进制补码时,没有与之相对应的正数INT_MIN

abs(INT_MIN) == -INT_MIN == undefined behavior
Run Code Online (Sandbox Code Playgroud)

在符号幅度表示中,有:

-INT_MIN == INT_MAX
Run Code Online (Sandbox Code Playgroud)

因此,abs()留下一些未定义的行为似乎是合理的。

一旦需要二进制补码,abs(INT_MIN)就可以完全指定行为,或者至少定义实现,这似乎是有意义的,而没有任何向后兼容的问题。但我看不到有任何建议的改变。

我看到的唯一缺点是C ++标准将需要abs()明确指定,而不是引用C标准的abs()。(据我所知,C并不要求补码。)

这是否只是委员会的优先事项?还是有理由不利用两国补编任务规定所提供的简化和确定性?

Bar*_*rry 10

该委员会考虑的具体问题之一是如何处理-INT_MIN,该民意调查的结果是:

加/减/乘和-INT_MIN溢出是当前未定义的行为,它应该是:

4:换行
6:换行或陷阱
5:中间值是数学整数
14:现状(仍未定义的行为)

人们对此进行了明确考虑,人们认为最好的选择是保持其未定义的行为。

为了阐明“中间值是数学整数”,本文的另一部分阐明了这(int)a + (int)b > INT_MAX可能是正确的。


请注意,在这种情况下,实现者可以选择定义特定的行为。我不知道他们有没有做。