在溢出的情况下,不要在stdint.h定义展出C99符号整型定义良好的行为? [英] Do C99 signed integer types defined in stdint.h exhibit well-defined behaviour in case of an overflow?

查看:217
本文介绍了在溢出的情况下,不要在stdint.h定义展出C99符号整型定义良好的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C(short,int和长等)表现出不确定的行为,如果他们得到外部的结果[TYPE_MIN,TYPE_MAX]区间内(在标准有符号整数类型的所有操作,其中TYPE_MIN,TYPE_MAX是最小和最大整数值分别可以由特定整数类型被存储

根据C99标准,但是,我们要求所有的 intN_t 类型有补重presentation:


  

7.8.11.1精确宽的整数类型结果
  1. typedef名intN_t表示与宽度N,没有填充一个符号整型
  位,以及一个二的补码重新presentation。因此,中int8_t表示符号整数
  恰好与8位的宽度类型。


这是否意味着一个整数溢出的情况下 intN_t 类型C99表现出明确的行为?例如,这是code明确定​​义?

 的#include<&stdio.h中GT;
#包括LT&;&stdint.h GT;
#包括LT&;&inttypes.h GT;INT主要(无效)
{
    的printf(最低的32位重presentable号:%PRId32\\ n,INT32_MAX + 1);
    返回0;
}


解决方案

没有,没有。

该类型的范围内的值的二进制补码再presentation要求并不意味着关于溢出行为的任何事情。

&LT的类型; stdint.h> 是简单类型定义(别名)为现有类型。添加一个typedef不会改变一个类型的行为。

C标准的6.5节第5段(包括C99和C11)仍然适用:


  

如果一个异常情况的的评估过程中发生
  前pression(即,如果结果不是数学上定义或
  未在其类型重新presentable值的范围),则该行为
  未定义。


这不会影响无符号类型,因为无符号的操作不会溢出;他们定义为产生包裹的结果,降低模的类型的_MAX + 1,除无符号类型比 INT 窄提升到(签字) INT ,并因此遇到同样的问题。例如,这

 无符号短X = USHRT_MAX;
无符号短Y = USHRT_MAX;
无符号短Z = X * Y;

将导致不确定的行为,如果 INT 窄。 (如 INT 16位和32位,分别接 65535 * 65535 收益率 4294836225 ,超过了 INT_MAX

All operations on "standard" signed integer types in C (short, int, long, etc) exhibit undefined behaviour if they yield a result outside of the [TYPE_MIN, TYPE_MAX] interval (where TYPE_MIN, TYPE_MAX are the minimum and the maximum integer value respectively. that can be stored by the specific integer type.

According to the C99 standard, however, all intN_t types are required to have a two's complement representation:

7.8.11.1 Exact-width integer types
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 a signed integer type with a width of exactly 8 bits.

Does this mean that intN_t types in C99 exhibit well-defined behaviour in case of an integer overflow? For example, is this code well-defined?

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    printf("Minimum 32-bit representable number: %" PRId32 "\n", INT32_MAX + 1);
    return 0;
}

解决方案

No, it doesn't.

The requirement for a 2's-complement representation for values within the range of the type does not imply anything about the behavior on overflow.

The types in <stdint.h> are simply typedefs (aliases) for existing types. Adding a typedef doesn't change a type's behavior.

Section 6.5 paragraph 5 of the C standard (both C99 and C11) still applies:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

This doesn't affect unsigned types because unsigned operations do not overflow; they're defined to yield the wrapped result, reduced modulo TYPE_MAX + 1. Except that unsigned types narrower than int are promoted to (signed) int, and can therefore run into the same problems. For example, this:

unsigned short x = USHRT_MAX;
unsigned short y = USHRT_MAX;
unsigned short z = x * y;

causes undefined behavior if short is narrower than int. (If short and int are 16 and 32 bits, respectively, then 65535 * 65535 yields 4294836225, which exceeds INT_MAX.)

这篇关于在溢出的情况下,不要在stdint.h定义展出C99符号整型定义良好的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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