📜 ⬆️ ⬇️

The whole truth about integer types in C

First, a few questions:

  1. Is char the default type signed or not? And int ?
  2. Is implicit conversion (signed char *) to (char *) ? And the same for int ?
  3. How many bits are in unsigned char ?
  4. What is the maximum number guaranteed to be placed in an int ? And the minimum?
  5. The long type is definitely bigger than char , isn't it?

Of course, experimentally looking for answers to these questions with the help of your favorite compiler in your favorite system on your favorite computer 1) is not the best idea. We are talking about the standard language (C99 and newer).

If you can confidently answer these questions correctly, then this article is not for you. Otherwise, the ten minutes spent reading it will be very useful.
')
I will assume that you answered
  1. Sign both.
  2. Both are legal.
  3. eight.
  4. 2,147,483,647. -2,147,48364 8 .
  5. Of course, cap.


And the correct answers are
  1. char - not regulated, int - signed.
  2. For int , legal, but not for char .
  3. At least 8.
  4. 32767. -3276 7
  5. Generally speaking, no.




About signed and unsigned


All integer types except char , are signed by default.

With char situation is more complicated. The standard establishes three different types: char , signed char , unsigned char . In particular, a type pointer (signed char *) cannot be implicitly cast to a type (char *) .

Although formally these are three different types, in fact, char equivalent to either signed char , or unsigned char — the choice of compiler (the standard does not require anything specific).

I wrote more about char in the comments .

About the size of unsigned char


The unsigned char type is an abstraction of a machine byte. The importance of this type is manifested in the fact that C can address memory only to within a byte. On most architectures, the byte size is 8 bits, but there are exceptions. For example, processors with a 36-bit architecture typically have a 9-bit byte, and in some Texas Instruments DSPs, the bytes are 16 or 32 bits. Ancient architectures can have short bytes of 4, 5, or 7 bits.

Standard C is forced to abandon antediluvian architectures and requires that the bytes be at least 8-bit. The specific value ( CHAR_BIT 2) ) for this platform is recorded in the header file limits.h .

Sizes of integer types in C


C is portable, therefore, in it the basic integer types ( char , short , int , etc.) do not have a strictly defined size, but depend on the platform. However, these types would not be portable if
their sizes were completely arbitrary: the standard establishes the minimum ranges of accepted values ​​for all basic integer types. Namely,


The standard requires that the maximum unsigned char value is 2 CHAR_BIT −1 (see previous paragraph).

The standard requires sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) . Thus, situations like sizeof(char)=sizeof(long)=32 are legitimate. For some DSPs from Texas Instruments, it is.

The specific values ​​of these ranges for this platform are indicated in the limits.h header file.

New types in C99


After C99 added the long long type, there are more integer types and confusion. To restore order, the standard entered the header file stdint.h , where types like int16_t (equal to 16 bits) are int_least16_t , int_least16_t (the minimum type capable of holding 16 bits), int_fast16_t (at least 16 bits, working with this type is the fastest on this platform), etc.

The least- and fast-types are in fact a replacement for the int , short , long and other types discussed above. In addition, they give the programmer a choice between speed and size.

From types like int16_t , with a strict indication of size, portability suffers: for example, a 16-bit register may simply not be found on an architecture with a 9-bit byte. Therefore, the standard here clearly says that these types are optional. But considering that no matter what code you write, a little less than in all cases, the target architecture is fixed even in the worst case to the nearest family (say, x86 or AVR), within which the size of a byte cannot suddenly change, the portability actually remains . Moreover, types like int16_t turned out to be even more popular than int_least16_t and int_fast16_t , and with low-level programming (microcontrollers, device drivers), and even more so, because there is often uncertainty about the size of a variable is simply impermissible.



1) For convenience, the top three architecture + OS + compiler will be referred to as simply a platform .
2) It would be UCHAR_BIT correct to call this macro UCHAR_BIT , but for reasons of compatibility it is called as it is called.

Source: https://habr.com/ru/post/156593/


All Articles