‘long’ 是否保证至少为 32 位?

发布于 2024-10-05 21:55:16 字数 2033 浏览 0 评论 0 原文

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

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

我从 3.9.1/2 推导出来:

  • 有四种有符号整数类型:“signed char”、“short int”、 “int”和“long int”。在这份名单中, 每种类型至少提供同样多的 存储与其前面的存储相同 列表。普通整数具有自然大小 由架构建议 执行环境
  • 此外,char的大小在3.9.1/中描述为:

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

    1.7/1 对此进行了更具体的定义:

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

    这使我得出以下结论:

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

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


    这篇文章中,Alf P. Steinbach 说:

    long 保证(至少)32 位。

    这与我所理解的 C++ 中根据标准的基本类型的大小的一切背道而驰。通常情况下,我会认为这个说法是初学者的错误,但由于这是阿尔夫,我认为值得进一步调查。

    那么,你说呢?标准是否保证 long 至少为 32 位?如果是,请具体说明如何做出此保证。我就是没看到。

    1. C++ 标准明确规定,为了了解 C++,您必须了解 C (1.2/1) 1

    2. C++ 标准隐式定义了 long 可以容纳的值的最小限制为 LONG_MIN-< code>LONG_MAX 2

    因此,无论 long 有多大,它都必须足够大以容纳 LONG_MIN 到 LONG_MAX。

    但 Alf 和其他人明确长整型必须至少为 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)在中定义为:

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

    By my reading of the C++ Standard, I have always understood that the sizes of the integral fundamental types in C++ were as follows:

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

    I deduced this from 3.9.1/2:

    1. There are four signed integer types: “signed char”, “short int”,
      “int”, and “long int.” In this list,
      each type provides at least as much
      storage as those preceding it in the
      list. Plain ints have the natural size
      suggested by the architecture of the
      execution environment

    Further, the size of char is described by 3.9.1/ as being:

    1. [...] large enough to store any member of the implementation’s basic character set.

    1.7/1 defines this in more concrete terms:

    1. The fundamental storage unit in the C + + memory model is the byte. A byte is at least large enough to contain any member of the basic execution character set and is composed of a contiguous sequence of bits, the number of which is implementation-defined.

    This leads me to the following conclusion:

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

    where sizeof tells us how many bytes the type is. Furthermore, it is implementation-defined how many bits are in a byte. Most of us are probably used to dealing with 8-bit bytes, but the Standard says there are n bits in a byte.


    In this post, Alf P. Steinbach says:

    long is guaranteed (at least) 32 bits.

    This flies in the face of everything I understand the size of the fundamental types to be in C++ according to the Standard. Normally I would just discount this statement as a beginner being wrong, but since this was Alf I decided it was worth investigating further.

    So, what say you? Is a long guaranteed by the standard to be at least 32 bits? If so, please be specific as to how this guarantee is made. I just don't see it.

    1. The C++ Standard specifically says that in order to know C++ you must know C (1.2/1) 1

    2. The C++ Standard implicitly defines the minimum limit on the values a long can accommodate to be LONG_MIN-LONG_MAX 2

    So no matter how big a long is, it has to be big enough to hold LONG_MIN to LONG_MAX.

    But Alf and others are specific that a long must be at least 32 bits. This is what I'm trying to establish. The C++ Standard is explicit that the number of bits in a byte are not specified (it could be 4, 8, 16, 42) So how is the connection made from being able to accommodate the numbers LONG_MIN-LONG_MAX to being at least 32 bits?


    (1) 1.2/1: The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

    • ISO/IEC 2382 (all parts), Information technology – Vocabulary
    • ISO/IEC 9899:1999, Programming languages – C
    • ISO/IEC 10646-1:2000, Information technology – Universal Multiple-Octet Coded Character Set (UCS) – Part 1: Architecture and Basic Multilingual Plane

    (2) Defined in <climits> as:

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

    如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

    扫码二维码加入Web技术交流群

    发布评论

    需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

    评论(5

    尽揽少女心 2024-10-12 21:55:16

    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
    

    因此可以保证 long 至少为 32 位。

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

    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::min()==LONG_MIN==(long)LONG_MINstd::numeric_limits::max()= =LONG_MAX==(长)LONG_MAX

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

    C++ uses the limits defined in the C standard (C++: 18.3.2 (c.limits), C: 5.2.4.2.1):

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

    So you are guaranteed that a long is at least 32 bits.

    And if you want to follow the long circuitous route to whether LONG_MIN/LONG_MAX are representable by a long, you have to look at 18.3.1.2 (numeric.limits.members) in the C++ standard:

    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.
    

    I moved the footnotes into the comment, so it's not exactly what appears in the standard. But it basically implies that std::numeric_limits<long>::min()==LONG_MIN==(long)LONG_MIN and std::numeric_limits<long>::max()==LONG_MAX==(long)LONG_MAX.

    So, even though the C++ standard does not specify the bitwise representation of (signed) negative numbers, it has to either be twos-complement and require 32-bits of storage in total, or it has an explicit sign bit which means that it has 32-bits of storage also.

    贪恋 2024-10-12 21:55:16

    答案是肯定的。阅读我的 OP 和所有评论以了解确切原因,但这是简短的版本。如果您对此有任何疑问或疑问,我鼓励您阅读整个帖子和所有评论。否则接受这一点:

    1. C++ 标准包含 C 标准的一部分,包括 LONG_MINLONG_MAX 的定义
    2. LONG_MIN 被定义为不大于比 -2147483647
    3. LONG_MAX 被定义为不小于 +2147483647
    4. 在 C++ 中,整数类型在底层表示中以二进制形式存储,
    5. 以便表示 <二进制的 code>-2147483647 和 +2147483647 ,您需要 32 位。
    6. C++ long 保证能够表示 LONG_MINLONG_MAX 的最小范围,

    因此 long 必须至少为 32 位1

    编辑:

    LONG_MINLONG_MAX 的值的大小由第 §5.2.4.2.1 节中的 C 标准 (ISO/IEC 9899:TC3) 规定:

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

    — 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 的硬件。

    The answer is definitively YES. Read my OP and all the comments to understand why exactly, but here's the short version. If you doubt or question any of this, I encourage you to read the entire thread and all of the comments. Otherwise accept this as true:

    1. The C++ standard includes parts of the C standard, including the definitions for LONG_MIN and LONG_MAX
    2. LONG_MIN is defined as no greater than -2147483647
    3. LONG_MAX is defined as no less than +2147483647
    4. In C++ integral types are stored in binary in the underlying representation
    5. In order to represent -2147483647 and +2147483647 in binary, you need 32 bits.
    6. A C++ long is guaranteed to be able to represent the minimum range LONG_MIN through LONG_MAX

    Therefore a long must be at least 32 bits1.

    EDIT:

    LONG_MIN and LONG_MAX have values with magnitudes dictated by the C standard (ISO/IEC 9899:TC3) in section §5.2.4.2.1:

    [...] Their implementation-defined values shall be equal or greater in magnitude [...] (absolute value) to those shown, with the same sign [...]

    — 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 bits: This does not mean that sizeof (long) >= 4, because a byte is not necessarily 8 bits. According to the Standard, a byte is some unspecified (platform-defined) number of bits. While most readers will find this odd, there is real hardware on which CHAR_BIT is 16 or 32.

    少年亿悲伤 2024-10-12 21:55:16

    C++ 标准指出 的内容与 C 标头 相同(ISO C++03 文档中的 18.2.2) )。

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

    — 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)
    

    The C++ standard notes that the contents of <climits> are the same as the C header <limits.h> (18.2.2 in ISO C++03 doc).

    Unfortunately, I do not have a copy of the C standard that existed pre-C++98 (i.e. C90), but in C99 (section 5.2.4.2.1), <limits.h> has to have at least this minimum values. I don't think this changed from C90, other than C99 adding the long long types.

    — 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)
    
    江挽川 2024-10-12 21:55:16

    是的,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 范围内的所有值(例如,长整型)。

    最后,shorts、ints 和 longs 都必须由整数个字符组成; sizeof() 始终报告整数值。此外,逐个字符地遍历内存必须访问每一位,这带来了一些实际限制。

    这些要求在任何方面都没有不一致。任何满足要求的尺寸都可以。

    很久以前就有机器的本机字长为 36 位。如果您要将 C++ 编译器移植到它们,您可以合法地决定在 char 中使用 9 位,在short 和 int 中使用 18 位,在 long 中使用 36 位。您还可以合法地决定在每种类型中使用 36 位,这与当今典型的 32 位系统上的 int 可以使用 32 位的原因相同。现实世界中存在使用 64 位字符的实现。

    另请参阅 C++ FAQ Lite 的第 26.1-6 和 29.5 节。

    Yes, the C++ standard is explicit that the number of bits in a byte is not specified. The number of bits in a long isn't specified, either.

    Setting a lower bound on a number is not specifying it.

    The C++ standard says, in one place:

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

    It says, in effect, in another place, via inclusion of the C standard:

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

    (except that AFAIK, the identifiers SHORT_BITS, INT_BITS and LONG_BITS don't exist, and that these limits are inferred by the requirements for minimum values on the types.)

    This follows from the fact that a certain number of bits are required, mathematically, to encode all of the values in the (e.g. for longs) LONG_MIN..LONG_MAX range.

    Finally, shorts, ints and longs must all be made up of an integral number of chars; sizeof() always reports an integral value. Also, iterating through memory char by char must access every bit, which places some practical limitations.

    These requirements are not inconsistent in any way. Any sizes that satisfy the requirements are OK.

    There were machines long ago with a native word size of 36 bits. If you were to port a C++ compiler to them, you could legally decide to have 9 bits in a char, 18 in both short and int, and 36 in long. You could also legally decide to have 36 bits in each of those types, for the same reason that you can have 32 bits in an int on a typical 32-bit system today. There are real-world implementations that use 64-bit chars.

    See also sections 26.1-6 and 29.5 of the C++ FAQ Lite.

    情愿 2024-10-12 21:55:16

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

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

    But Alf and others are specific that a
    long must be at least 32 bits. This is
    what I'm trying to establish. The C++
    Standard is explicit that the number
    of bits in a byte are not specified.
    Could be 4, 8, 16, 42... So how is the
    connection made from being able to
    accomodate the numbers
    LONG_MIN-LONG_MAX to being at least 32
    bits?

    You need 32 bits in the value representation in order to get at least that many bitpatterns. And since C++ requires a binary representation of integers (explicit language to that effect in the standard, §3.9.1/7), Q.E.D.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文