barak manos
barak manos

Reputation: 30136

Integer types in C and C++, and their interpretation by printf

I have recently answered a question on SO, and found myself a bit uncertain of a few facts myself during the process, so I would like to get a second assertion of these facts:

  1. Integer types in C and C++:

    • char: an integer value with the size of 1 byte.

    • short: an integer value with the size of 2 bytes.

    • long: an integer value with the size of 4 bytes.

    • long long: an integer value with the size of 8 bytes.

    The types short, long and long long are usually followed by int.

    It is not a must, however, and we can use them without the int.

    Alternatively, we can just state int, but that might be interpreted differently by different compilers.

    So to summarize this:

    • short is the same as short int but not necessarily the same as int.

    • long is the same as long int but not necessarily the same as int.

    • long long is the same as long long int but not necessarily the same as int.

    • On a given compiler, int is either short int or long int or long long int.

  2. Printing an integer using printf:

    -printf("%d"...) reads an int value from the stack.

    -printf("%ld"...) reads a long int value from the stack.

    -printf("%lld"...) reads a long long int value from the stack.

    So:

    -printf("%ld"...) will read 4 bytes on any given platform.

    -printf("%lld"...) will read 8 bytes on any given platform.

    -printf("%d"...) will read 2 bytes or 4 bytes or 8 bytes, depending on the definition of int on the given platform.

Are there any cavities in the description above?

Thanks

Upvotes: 2

Views: 1678

Answers (4)

chux
chux

Reputation: 153377

Many questions....
Many answers....

OP: long: an integer value with the size of 4 bytes.
A: long is an integer with the minimum range of -2147483647 to +2147483647, thus it needs at least 32 bits.

OP: long long: an integer value with the size of 8 bytes.
A: long long is an integer with the minimum range of -9223372036854775807 to +9223372036854775807, thus it needs at least 64 bits.

OP: The types short, long and long long are usually followed by int.
A: I see short, long and long long more often by themselves then with a following int, unless it is in a pedantic usage like the C spec.
A: Further (not my opinion): short int i is the same as short i. long int i is the same as long i. long int i is the same as long i.
A: Further: short signed int i is the same as short i. short, signed, int may occur in any order with the same result.

OP: It is not a must, however, and we can use them without the int.
A: Yes. See above.

OP: Alternatively, we can just state int, but that might be interpreted differently by different compilers.
A: The size/range may change, but short is the same as signed shortis the same as signed short intis the same as signed int. This holds true with 'long' and 'long long', but not with 'char'.

OP: short is the same as short int but not necessarily the same as int.
A: Yes.

OP: long is the same as long int but not necessarily the same as int.
A: Yes.

OP: long long is the same as long long int but not necessarily the same as int.
A: Yes.

OP: On a given compiler, int is either short int or long int or long long int.
A: No. All 4 may be different size/range.

OP: -printf("%d"...) reads an int value from the stack.
OP: -printf("%ld"...) reads a long int value from the stack.
OP: -printf("%lld"...) reads a long long int value from the stack.
A: Yes - other mechanisms other than "stack" exist. Better to think of the int coming from a variadic parameter.

OP: -printf("%ld"...) will read 4 bytes on any given platform.
OP: -printf("%lld"...) will read 8 bytes on any given platform.
OP: -printf("%d"...) will read 2 bytes or 4 bytes or 8 bytes, depending on the definition of int on the given platform.
A: No. The size of a long is at least as much as int. The size of a long long is at least as much as long. The number of bytes read is platform dependent.

The definition of a "byte" in C is "addressable unit of data storage large enough to hold any member of the basic character set of the execution environment". So sizeof(char) --> 1 or in C parlance 1 byte, whether its 8, 9, 32, or whatever bit size.

In the larger world many folks consider a "byte" to be 8 bits. These two "byte" definition can confuse. When talking C, I prefer to say something like "The size of a short is 4" meaning sizeof(int) --> 4 or twice as much as char, without using the word "byte".

Upvotes: 2

Fiddling Bits
Fiddling Bits

Reputation: 8861

Some of your assertions are not correct, as they vary from platform to platform. To know with certitude the width of your types, open up your limits.h and float.h files. You can also use the sizeof operator.

Keep in mind that a char is always one byte, regardless of how many bits it has. That is, on some machines a char is 8 bits and on another a char is 16 bits. In each case, it is considered one byte. Other types are multiples of char.

Upvotes: 1

Ned
Ned

Reputation: 957

You cannot say with certainty, what the size of any of the integer types are for a given platform without consulting limits.h and, possibly, stdint.h. However, you can be sure that the printf format string associates the correct patterns with the correctly sized integers passed on the stack for a given implementation.

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490108

There are a couple of fairly major holes.

A char always occupies 1 byte. That's the only type for which the size is guaranteed though. All the others are basically 1 or more bytes, and large enough to hold a specified range of values (16 bits for short or int, 32 bits for long and 64 bits for long long).

In other words the sizes you've given are pretty common, but not guaranteed.

With printf:

  • "%d" specifies an int
  • "%ld" specifies a long int
  • "%lld" specifies a long long int.

As above, each of these has a specified minimum range, but not a required size.

Likewise, the standard doesn't actually specify that the machine have a stack (and a few, such as IBM mainframes and old Crays, don't), though if you consider only abstract behavioral requirements, then what you get is certainly LIFO (stack-like) requirements.

Upvotes: 6

Related Questions