c++ - C++17 中的算术溢出

标签 c++ x86 g++ clang language-lawyer

  1. uint8_tuint16_tuint32_tuint64_t 是否根据 C++17 明确定义了算术溢出?如果是,定义的行为是什么(高度赞赏 C++ 标准的摘录)
  2. int8_tint16_tint32_tint64_t 是否根据 C++17 明确定义了算术溢出? (高度赞赏 C++ 标准的摘录)
  3. 如果以上任何一项或全部是特定于实现的,那么 g++ 和 clang 的定义是什么?
  4. 如果它是特定于体系结构的(如 Havenard 所指出的),我的问题是特定于 x86(-64) 的。
  5. 如果我做更小的无符号整数 - 更大的无符号整数,它是否定义明确?

我看到了这个post的第一个答案在我的问题 #1 中提到,它是在 C 标准中定义的,尽管他没有引用它,而且我在 C++ 标准中找不到任何相关信息。

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

更新 1:

删除了每个 ach 的“下溢”,因为它是错误的术语(感谢@ach)。添加了 #5 来表达我所说的“下溢”(不正确)的真正含义

最佳答案

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

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

Unsigned integers shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer. (44) This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

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

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

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

void a();
void b();

void foo(int k) {
    int z = k+1;
    if (z < k) {
        a();
    } else {
        b();
    }
}

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

关于c++ - C++17 中的算术溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52819778/

相关文章:

c++ - 我的编译行和我的 makefile 之间有什么区别会导致错误?

c++ - C++ 中函数签名的定义顺序

linux-kernel - in_irq() 可靠吗?

delphi - 调用汇编语言函数导致 "floating point stack check"异常

g++ 中的 C++11 语言支持,没有 `-std=c++11` 的库破坏功能

c++ - return 语句是否会阻止递归堆栈继续?

c++ - 如何在windows上获取cpu上的实际内核数?

c++ - 32 位 x86 上的 64 位 int 算术(来自 c )

c++ - 为什么我不能链接到 shaderc?

c++ - 使用 libcurl 的 CA 证书身份验证