`long`保证至少为32位?

时间:2010-12-01 22:24:33

标签: c++ standards long-integer language-lawyer

通过阅读C ++标准,我一直都知道C ++中整数基本类型的大小如下:

sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

我从3.9.1 / 2中推断出这一点:

  
      
  1. 有四种有符号整数类型:“signed char”,“short int”,   “int”和“long int。”在此列表中,   每种类型至少提供相同的数量   存储作为之前的存储   名单。普通锭具有自然尺寸   建筑的建议   执行环境
  2.   

此外,char的大小由3.9.1 /描述为:

  
      
  1. [...]足以存储实现的基本字符集的任何成员。
  2.   

1.7 / 1以更具体的术语定义了这一点:

  
      
  1. C ++内存模型中的基本存储单元是字节。一个字节至少足以包含基本执行字符集的任何成员,并且由一个连续的位序列组成,其数量是实现定义的。
  2.   

这使我得出以下结论:

1 == sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

其中sizeof告诉我们该类型的字节数。此外,它是实现定义的字节中有多少位。我们大多数人可能习惯于处理8位字节,但标准表示字节中有n位。


this post中,Alf P. Steinbach说:

  

长保证(至少)32位。

根据标准,我对C ++中基本类型的大小有所了解。通常情况下,我只是将这句话视为初学者错误,但由于这是Alf,我认为值得进一步调查。

那么,你说什么?标准长期保证至少为32位?如果是这样,请具体说明如何进行此保证。我只是没有看到它。

  1. C ++标准明确指出,为了了解C ++,您必须知道C(1.2 / 1) 1

  2. C ++标准隐含地定义了long可以容纳的值的最小限制LONG_MIN - LONG_MAX 2

  3. 所以无论long有多大,它都必须足够大才能将LONG_MIN保持为LONG_MAX。

    但是Alf和其他人具体,long必须至少为32位。这就是我想要建立的。 C ++标准明确指出一个字节中的位数没有被指定(它可能是4,8,16,42)那么连接如何能够容纳数字LONG_MIN-LONG_MAX至少是32位?


    (1)1.2 / 1:以下参考文件对于本文件的应用是必不可少的。凡是注日期的引用文件,仅引用的版本适用。凡是不注日期的引用文件,其最新版本(包括所有的修改单)适用于。

    • ISO / IEC 2382(所有部分),信息技术 - 词汇
    • ISO / IEC 9899:1999,编程语言 - C
    • ISO / IEC 10646-1:2000,信息技术 - 通用多八位编码字符集(UCS) - 第1部分:体系结构和基本多语言平面

    (2)在<climits>中定义为:

    LONG_MIN -2147483647 // -(2^31 - 1)
    LONG_MAX +2147483647 //   2^31 - 1
    

5 个答案:

答案 0 :(得分:35)

C ++使用C标准中定义的限制(C ++:18.3.2(c.limits),C:5.2.4.2.1):

LONG_MIN -2147483647 // -(2^31 - 1)
LONG_MAX +2147483647 //   2^31 - 1

因此,您可以保证长度至少为32位。

如果您想遵循LONG_MIN / LONG_MAX是否可由long表示的漫长迂回路线,您必须查看18.3.1.2(numeric.limits.members )在C ++标准中:

static constexpr T min() throw(); // Equivalent to CHAR_MIN, SHRT_MIN, FLT_MIN, DBL_MIN, etc.
static constexpr T max() throw(); // Equivalent to CHAR_MAX, SHRT_MAX, FLT_MAX, DBL_MAX, etc.

我将脚注移到评论中,所以它并不是标准中出现的内容。但它基本上意味着std::numeric_limits<long>::min()==LONG_MIN==(long)LONG_MINstd::numeric_limits<long>::max()==LONG_MAX==(long)LONG_MAX

因此,即使C ++标准没有指定(带符号)负数的按位表示,它也必须是二进制补码并且总共需要32位存储,或者它具有明确的符号位,这意味着它也有32位存储空间。

答案 1 :(得分:16)

答案肯定是肯定的。阅读我的OP和所有评论,以了解原因,但这是短版本。如果您怀疑或质疑这一点,我建议您阅读整个主题和所有评论。否则接受这个为真:

  1. C ++标准包含C标准的部分内容,包括LONG_MINLONG_MAX的定义
  2. LONG_MIN定义为不大于-2147483647
  3. LONG_MAX定义为不低于+2147483647
  4. 在C ++中,整数类型以二进制形式存储在基础表示中
  5. 为了用二进制表示-2147483647+2147483647,您需要32位。
  6. C ++ long保证能够代表最小范围LONG_MINLONG_MAX
  7. 因此long必须至少为32位 1

    编辑:

    LONG_MINLONG_MAX具有C标准(ISO / IEC 9899:TC3)在第5.2.4.2.1节中规定的数值:

      

    [...]它们的实现定义值的大小[...](绝对值)应等于或大于显示的值,具有相同的符号[...]

    — minimum value for an object of type long int
    LONG_MIN -2147483647 // -(2 ^ 31 - 1)
    — maximum value for an object of type long int
    LONG_MAX +2147483647 // 2 ^ 31 - 1
    

    1 32位:这并不意味着sizeof (long) >= 4,因为一个字节不一定是8位。根据标准,字节是一些未指定的(平台定义的)位数。虽然大多数读者会觉得这很奇怪,但真正的硬件CHAR_BIT是16或32。

答案 2 :(得分:7)

C ++标准指出<climits>的内容与C头<limits.h>(ISO C ++ 03 doc中的18.2.2)相同。

不幸的是,我没有C ++ 98之前存在的C标准副本(即C90),但在C99(第5.2.4.2.1节)中,<limits.h>必须至少有这个最小值。除了C99添加long long类型之外,我认为这不会改变C90。

— minimum value for an object of type long int

LONG_MIN -2147483647 // −(2^31 − 1)

— maximum value for an object of type long int

LONG_MAX +2147483647 // 2^31 − 1

— maximum value for an object of type unsigned long int

ULONG_MAX 4294967295 // 2^32 − 1

— minimum value for an object of type long long int

LLONG_MIN -9223372036854775807 // −(2^63− 1)

答案 3 :(得分:7)

  但是阿尔法和其他人都是具体的   long必须至少为32位。这是   我正在努力建立什么。 C ++   标准是明确的数字   未指定字节中的位数。   可能是4,8,16,42 ......那么怎么样?   由能够做出的连接   容纳数字   LONG_MIN-LONG_MAX至少为32   位?

您需要在值表示中使用32位才能获得至少那么多位模式。而且由于C ++需要整数的二进制表示(在标准中使用显式语言,§3.9.1/ 7),Q.E.D。

答案 4 :(得分:6)

是的,C ++标准明确指出未指定字节中的位数。也没有指定long中的位数。

在数字上设置下限并非指定

C ++标准在一个地方说:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

它实际上是通过包含C标准在另一个地方说的:

CHAR_BITS >= 8; SHORT_BITS >= 16; INT_BITS >= 16; LONG_BITS >= 32

(除了AFAIK,标识符SHORT_BITS,INT_BITS和LONG_BITS不存在,并且这些限制是根据类型的最小值要求推断出来的。)

这是因为在数学上需要一定数量的比特来编码(例如,对于长期)LONG_MIN..LONG_MAX范围内的所有值。

最后,短裤,短片和长片必须全部由多个字符组成; sizeof()始终报告一个整数值。此外,通过char迭代内存char必须访问每个位,这带来了一些实际限制。

这些要求不以任何方式不一致。任何满足要求的尺寸都可以。

很久以前有机器,本机字大小为36位。如果你要将C ++编译器移植到它们,你可以合法地决定在一个char中有9位,在short和int中有18位,在long中有36位。您也可以在法律上决定在每种类型中使用36位,原因与今天在典型32位系统上的int中可以有32位相同。有些实际的实现使用64位字符。

另见C++ FAQ Lite的第26.1-6和29.5节。