C++中的算术溢出17

HCS*_*CSF 2 c++ x86 g++ clang language-lawyer

  1. 在算术溢流井每C++ 17定义uint8_t,uint16_t,uint32_t,uint64_t?如果是,那么定义的行为是什么(来自C++标准的摘录非常感谢)
  2. 在算术溢流井每C++ 17定义int8_t,int16_t,int32_t,int64_t?(摘自C++标准非常感谢)
  3. 如果上面的任何一个或全部是特定于实现的,那么g ++和clang的定义是什么?
  4. 如果它是特定于体系结构的(正如Havenard指出的那样),我的问题特定于x86(-64).
  5. 如果我做一个较小的unsigned int - 更大的unsigned int,它定义得很好怎么办?

我看到这篇文章的第一个答案提到我的问题#1,它是用C标准定义的,虽然他没有引用它,我在C++标准中找不到任何东西.

=================

更新1:

因为它是错误的术语而删除了每次"下溢"(感谢@ach).添加了#5来表达我对"下溢"的真正含义(错误)

Ser*_*eyA 6

为了创建规范,这里有一些规范性规范(引自最新的C++草案):

  • 无符号整数不会溢出:见6.7.1:

无符号整数应遵守算术模2n的定律,其中n是该特定整数大小的值表示中的位数.(44)这意味着无符号算术不会溢出,因为无法用结果无符号整数类型表示的结果以比模式生成的无符号整数类型所表示的最大值大1的数量为模.

  • 有符号整数溢出/下溢未定义:见7.1.4:

如果在评估表达式期间,结果未在数学上定义或未在其类型的可表示值范围内,则行为未定义.

顺便说一句,它们都不是特定于实现的,并且编译器积极地利用上溢/下溢进行优化.例如,如以下代码段所示:

void a();
void b();

void foo(int k) {
    int z = k+1;
    if (z < k) {
        a();
    } else {
        b();
    }
}
Run Code Online (Sandbox Code Playgroud)

https://gcc.godbolt.org/z/0re-nM - 分支被删除,即使在真实平台上由于模2表示,z实际上可能变得比较小k.

  • 基本上在你的例子中,'z`保证在`if`语句中等于`k`,因为它们是相同的(即使是'++ k`未定义),因此编译器可以安全地消除我认为这个分支. (2认同)