For integral / arithmetic types in C and C ++

I know that the C ++ standard explicitly guarantees the size of only char , signed char and unsigned char . In addition, it gives guarantees that, say, short , at least, has a char , int value of short size, etc. But there are no explicit guarantees regarding the absolute value, say, sizeof(int) . It was information in my head, and I lived with it happily. Some time ago, however, I came across a comment in SO (I can’t find it) that in C long should be at least 4 bytes guaranteed, and this requirement is “inherited” from C ++. This is true? If so, what other implicit guarantees do we have for sizes of arithmetic types in C ++? Please note that I am absolutely not interested in practical guarantees on different platforms in this matter, only theoretical.

+7
c ++ c sizeof primitive-types
source share
7 answers

18.2.2 ensures that <climits> has the same contents as the C library header <limits.h> .

The ISO C90 standard is hard to understand, which is a shame given that C ++ relies on it, but the Numerical Limits section (numbered 2.2.4.2 in a random draft that I once discovered and have a false around) gives minimum values ​​for constants INT_MAX etc. in <limits.h> . For example, ULONG_MAX must be at least 4294967295, from which we infer that the width of long is at least 32 bits.

There are similar restrictions in the C99 standard, but of course, these are not the ones that C ++ 03 refers to.

This does not guarantee that long is at least 4 bytes, since in C and C ++, "byte" is mainly defined as "char", and it is not guaranteed that CHAR_BIT is 8 in C or C ++. CHAR_BIT == 8 guaranteed by both POSIX and Windows.

+13
source share

I do not know about C ++. In C you

                                   Annex E
                               (informative)


                           Implementation limits

        [# 1] The contents of the header are given below,
        in alphabetical order.  The minimum magnitudes shown shall
        be replaced by implementation-defined magnitudes with the
        same sign.  The values ​​shall all be constant expressions
        suitable for use in #if preprocessing directives.  The
        components are described further in 5.2.4.2.1.

                #define CHAR_BIT 8
                #define CHAR_MAX UCHAR_MAX or SCHAR_MAX
                #define CHAR_MIN 0 or SCHAR_MIN
                #define INT_MAX +32767
                #define INT_MIN -32767
                #define LONG_MAX +2147483647
                #define LONG_MIN -2147483647
                #define LLONG_MAX +9223372036854775807
                #define LLONG_MIN -9223372036854775807
                #define MB_LEN_MAX 1
                #define SCHAR_MAX +127
                #define SCHAR_MIN -127
                #define SHRT_MAX +32767
                #define SHRT_MIN -32767
                #define UCHAR_MAX 255
                #define USHRT_MAX 65535
                #define UINT_MAX 65535
                #define ULONG_MAX 4294967295
                #define ULLONG_MAX 18446744073709551615

So char <= short <= int <= long <= long long

and

CHAR_BIT * sizeof (char)> = 8
CHAR_BIT * sizeof (short)> = 16
CHAR_BIT * size (int)> = 16
CHAR_BIT * sizeof (long)> = 32
CHAR_BIT * sizeof (long long)> = 64

+12
source share

Yes, sizes like C ++ are inherited from C89.

I can not find the specification right now. But this is the Bible .

+3
source share

Remember that the guaranteed ranges of these types are one less than on most machines:

char -127 ... +127 is signed, but most machines with two additional devices have -128 ... + 127

Similarly for larger types.

+3
source share

There are several inaccuracies in what you read. These inaccuracies were either present in the source, or maybe you remembered it incorrectly.

Firstly, a pedantic remark about one peculiar difference between C and C ++. The C language makes no guarantees regarding the relative sizes of integer types (in bytes). C only gives guarantees regarding their relative ranges. It is true that an int range is always no less than a short range, etc. However, it is formally permitted by the C standard to have sizeof(short) > sizeof(int) . In this case, the extra bits in short will serve as padding bits that are not used to represent values. Obviously, this is something that is simply permitted by the legal language in the standard, and not by those whom anyone may encounter in practice.

In C ++, on the other hand, the language specification guarantees guarantees of both relative ranges and relative sizes of types, therefore in C ++, in addition to the above relationship relations inherited from C, it is guaranteed that sizeof(int) greater than or greater than sizeof(short) .

Secondly, the C language standard guarantees a minimum range for each integer type (these guarantees are present in both C and C ++). Knowing the minimum range for a given type, you can always tell how many bits to form values ​​of this type you need to have (as the minimum number of bits). For example, it is true that the long type must have at least 32 bits to form values ​​in order to satisfy the requirements of the range. If you want to convert this to bytes, it will depend on what you mean by byte of the term. If you are talking specifically about 8-bit bytes, then indeed the long type will always consist of at least four 8-bit bytes. However, this does not mean that sizeof(long) always at least 4, since in the terminology of C / C ++ the term byte refers to char objects. char objects are not limited to 8 bits. In some implementation, it is entirely possible to have a 32-bit char type, which means that sizeof(long) in C / C ++ bytes may be legal, for example.

+2
source share

The C standard does not explicitly state that long must be at least 4 bytes, but they specify a minimum range for different integral types, which implies a minimum size.

For example, the minimum range for an unsigned long is 0 to 4,294,967,295. You need at least 32 bits to represent each individual number in that range. So yes, the standard guarantee is (indirectly) that long is at least 32 bits.

C ++ inherits data types from C, so you need to look at the C standard. In this case, the C ++ standard actually refers to parts of the C standard.

+1
source share

Just be careful that some machines have characters larger than 8 bits. For example, IIRC on TI C5x is 32 bits long, but sizeof (long) == 2, since characters, shorts and ints are all 16 bits with sizeof (char) == 1.

+1
source share

All Articles