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

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

问题描述

我们知道,有符号整数溢出是未定义的行为。但有一些有趣的C ++ 11 cstdint 文档:


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


请参阅link



这里是我的问题:因为标准明确说明 int8_t int16_t int32_t int64_t 负数是2的补码,这些类型未定义的行为?



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



C ++ 11,§18.4.1:


标题定义所有函数,类型,和


C11,§7.20.1.1:


typedef名称 intN_t 表示宽度为N的有符号整数类型,无填充位和二进制补码表示形式。因此, int8_t 表示这样一个宽度为8位的有符号整数类型。





$ b

是。根据C ++ 11标准的第5/4节(一般来说,任何表达式):


如果在计算表达式期间,结果不是数学定义的,或者不在其类型的
可表示值的范围内,则行为未定义。 [...]


二进制补码表示用于这些有符号类型的事实并不意味着算术模2 ^



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


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

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


46)这意味着无符号算术不会溢出,由结果
无符号整数类型表示的数字减去模数,该数字大于可以由
表示的最大值的一个数,得到无符号整数类型。



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

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)

See link

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?

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

C++11, §18.4.1:

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

C11, §7.20.1.1:

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?

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

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.

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

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

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) 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天全站免登陆