3-byte int and 5-byte long?

前端 未结 4 1336
独厮守ぢ
独厮守ぢ 2020-11-29 08:39

Does each of C and C++ standards allow sizeof of numeric types not to be a power of two?

The following constraints are known:

相关标签:
4条回答
  • 2020-11-29 09:00

    Definitely there are platforms with 24-bit ints. This is still used today for certain embedded applications. You could check Wikipedia for further information: http://en.wikipedia.org/wiki/24-bit

    0 讨论(0)
  • 2020-11-29 09:14

    TL;DR

    The behavior is valid and such compilers/architectures do exist

    • TI C5500/C6000 with 4-byte int, 5-byte long
    • Motorola DSP5600x/3xx series with 2-byte short, 3-byte int, 6-byte long
    • x86 with 8-byte double, 10-byte long double

    The number of bits used to represent the type long is not always the same as, or an integer multiple of, the number of bits in the type int. The ability to represent a greater range of values (than is possible in the type int) may be required, but processor costs may also be a consideration...

    Derek M. Jones' The New C Standard (Excerpted material) - An Economic and Cultural Commentary


    The other answer have already recapped C++ standard requirements. Similarly C standard also doesn't constrain the type (floating-point or integer) sizes in bytes to powers of 2. The most common example is long double, which is most often 10 bytes in x86 (with padding to 12 or 16 bytes in many modern compilers).

    ISO/IEC 9899:1999 (E)

    5.2.4.2.1 Sizes of integer types

    1. The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, the following shall be replaced by expressions that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign. [...]

    6.2.5 Types

    1. There are five standard signed integer types, designated as signed char, short int, int, long int, and long long int. (These and other types may be designated in several additional ways, as described in 6.7.2.) There may also be implementation-defined extended signed integer types.28)
      The standard and extended signed integer types are collectively called signed integer types.29)

    2. For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type.


    Odd-sized integer types are much rarer, but still exist. Many DSPs have standard-conforming compilers with non-power-or-2 types where int has 32 bits, long has 40 bits.

    long is

    • 40 bits or 5 bytes for C6000 COFF. This is fully compliant with any major C/C++ standard as those standards are all defining a minimum requirement of 4 byte for long (aka. long int). Programmers are often falsely assuming this type having a size of exactly 4 bytes.

    Emphasis mine
    C89 Support in TI Compilers#Misunderstandings about TI C

    Offside note: On some TI targets even long long is also a 32 or 40-bit type, which is valid in C89 as an extension but violates C99

    Some targets have long long (an extension from C99), but not a conforming one. C99 requires at least 64 bits, but C2700 has 32-bit long long, and C5500 has 40-bit long long. C2800, C6000, and ARM have 64-bit long long, and C5400 and MSP430 do not support long long. This is not technically a violation of C89, since this is actually an extension, but if we start supporting C99, this would be a violation of C99 (C99 5.2.4.2.1 "Sizes of integer types " para 1).

    The wider type's size doesn't even have to be a multiple of its preceding type's size. Continuing with what Derek M. Jones said in The New C Standard (Excerpted material): An Economic and Cultural Commentary

    ... For instance, the Texas Instruments TMS320C6000, a DSP processor, uses 32 bits to represent the type int and 40 bits to represent the type long (this choice is not uncommon). Those processors (usually DSP) that use 24 bits to represent the type int, often use 48 bits to represent the type long. The use of 24/48 bit integer type representations can be driven by application requirements where a 32/64-bit integer type representation are not cost effective.

    In all 24-bit DSPs I had known before, CHAR_BIT == 24 and all types have sizes as multiples of 24 bits, but I've just found out that the Motorola DSP5600x/3xx series have a really "strange" type system

    Data Type           size in bits
    (un)signed char     8
    (un)signed short    16
    (un)signed int      24
    (un)signed long     48
    (long)_fract        24 (48)
    pointer             16/24
    float/double        24+8
    enum                24
    

    So in this case sizeof(char) == 1 and sizeof(short) == 2 but sizeof(int) == 3 and sizeof(long) == 6

    Unfortunately GCC calls them (long and long long) double-word integers, and so do most people, making a big misunderstanding, although it doesn't necessarily be double the size.

    0 讨论(0)
  • 2020-11-29 09:19

    I think 3.9.1/2 (C++98) sums this up nicely (immediately followed by analogous information for the unsigned types):

    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 environment39) ; the other signed integer types are provided to meet special needs.

    Basically all we know is that sizeof(char) == 1 and that each "larger" type is at least that large, with int being a "natural" size for an architecture (where as far as I can tell "natural" is up to the compiler writer). We don't know anything like CHAR_BIT * sizeof(int) <= 32 etc. Also keep in mind that CHAR_BIT doesn't have to be 8 either.

    It seems fairly safe to say that three byte int and five byte long would be allowed for hardware where those sizes were natively used. I am however not aware of any such hardware/architectures.

    EDIT: As pointed out in @Nigel Harper comment we do know that int has to be at least 16 bits and long at least 32 bits to satisfy range requirements. Otherwise we don't have any specific size restrictions other than as seen above.

    0 讨论(0)
  • 2020-11-29 09:22

    The C++ standard (and almost certainly the C standard, but I haven't looked at it for a very long time) does not have a rule that says anything about the NUMBER of bits that a type should be. I know for a fact that 9-bit char is allowed, and there are machines with 36-bit integers. Last time I checked, neither 9 or 36 are powers of 2.

    0 讨论(0)
提交回复
热议问题