有符号整数溢出在 C++ 中仍然是未定义的行为吗? [英] Is signed integer overflow still undefined behavior in C++?

查看:39
本文介绍了有符号整数溢出在 C++ 中仍然是未定义的行为吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,有符号整数溢出是未定义的行为.但是在 C++11 cstdint 文档中有一些有趣的东西:

As we know, signed integer overflow is undefined behavior. But there is something interesting in C++11 cstdint documentation:

宽度分别为 8、16、32 和 64 位的有符号整数类型,没有填充位,对负值使用 2 的补码(仅当实现直接支持该类型时才提供)>

signed integer type with width of exactly 8, 16, 32 and 64 bits respectively with no padding bits and using 2's complement for negative values (provided only if the implementation directly supports the type)

见链接

这是我的问题:因为标准明确规定对于 int8_tint16_tint32_tint64_t> 负数是 2 的补码,这些类型的溢出仍然是未定义的行为吗?

And here is my question: since the standard says explicitly that for int8_t, int16_t, int32_t and int64_t negative numbers are 2's complement, is still overflow of these types an undefined behavior?

编辑我检查了 C++11 和 C11 标准,这是我发现的:

Edit I checked C++11 and C11 Standards and here is what I found:

C++11,第 18.4.1 节:

C++11, §18.4.1:

头文件定义了与 C 标准中的 7.20 相同的所有函数、类型和宏.

The header defines all functions, types, and macros the same as 7.20 in the C standard.

C11,第 7.20.1.1 节:

C11, §7.20.1.1:

typedef 名称 intN_t 指定宽度为 N、无填充位和二进制补码表示的有符号整数类型.因此,int8_t 表示宽度正好为 8 位的有符号整数类型.

The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits.

推荐答案

这些类型的溢出仍然是未定义的行为吗?

is still overflow of these types an undefined behavior?

是.根据 C++11 标准的第 5/4 段(关于任何一般表达式):

Yes. Per Paragraph 5/4 of the C++11 Standard (regarding any expression in general):

如果在表达式求值过程中,结果不是数学定义的或不在以下范围内其类型的可表示值,行为未定义.[...]

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. [...]

对于那些有符号类型使用二进制补码表示的事实并不意味着在评估这些类型的表达式时使用算术模 2^n.

The fact that a two's complement representation is used for those signed types does not mean that arithmetic modulo 2^n is used when evaluating expressions of those types.

另一方面,关于无符号算术,标准明确规定(第 3.9.1/4 段):

Concerning unsigned arithmetic, on the other hand, the Standard explicitly specifies that (Paragraph 3.9.1/4):

无符号整数,声明为 unsigned应遵守算术模 2^n 的法则,其中 n 是数字特定大小的整数的值表示中的位数

Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2^n where n is the number of bits in the value representation of that particular size of integer

这意味着无符号算术运算的结果总是数学定义",并且结果总是在可表示的范围内;因此,5/4 不适用.脚注 46 解释了这一点:

This means that the result of an unsigned arithmetic operation is always "mathematically defined", and the result is always within the representable range; therefore, 5/4 does not apply. Footnote 46 explains this:

46) 这意味着 unsigned 算术不会溢出,因为结果不能由结果表示无符号整数类型以比可以表示的最大值大 1 的数为模减少结果无符号整数类型.

46) 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.

这篇关于有符号整数溢出在 C++ 中仍然是未定义的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆