Reputation: 29146
According to C99 §5.2.4.2.1-1 the following types have size which is implementation dependant. What is said is they are equal or greater in magnitude than these values:
short >= 8 bits
int >= 16 bits
long >= 32 bits
long long >= 64 bits
I have always heard that long
is always 32-bits
, and that it is strictly equivalent to int32_t
which looks wrong.
What is true?
Upvotes: 6
Views: 1084
Reputation: 263617
I have always heard that
long
is always 32-bits and it is strictly equivalent toint32_t
which looks wrong.
I'm curious where you heard that. It's absolutely wrong.
There are plenty of systems (mostly either 16-bit or 32-bit systems or 64-bit Windows, I think) where long
is 32 bits, but there are also plenty of systems where long
is 64 bits.
(And even if long
is 32 bits, it may not be the same type as int32_t
. For example, if int
and long
are both 32 bits, they're still distinct types, and int32_t
is probably defined as one or the other.)
$ cat c.c
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("long is %zu bits\n", sizeof (long) * CHAR_BIT);
}
$ gcc -m32 c.c -o c && ./c
long is 32 bits
$ gcc -m64 c.c -o c && ./c
long is 64 bits
$
The requirements for the sizes of the integer types are almost as you stated in your question (you had the wrong size for short
). The standard actually states its requirements in terms of ranges, not sizes, but that along with the requirement for a binary representation implies minimal sizes in bits. The requirements are:
char
, unsigned char
, signed char
: 8 bitsshort
, unsigned short
: 16 bitsint
, unsigned int
: 16 bitslong
, unsigned long
: 32 bitslong long
, unsigned long long
: 64 bitsEach signed type has a range that includes the range of the previous type in the list. There are no upper bounds.
It's common for int
and long
to be 32 and 64 bits, respectively, particularly on non-Windows 64-bit systems. (POSIX requires int
to be at least 32 bits.) long long
is exactly 64 bits on every system I've seen, though it can be wider.
Upvotes: 4
Reputation: 123568
Note that the Standard doesn't specify sizes for types like int
, short
, long
, etc., but rather a minimum range of values that those types must be able to represent.
For example, an int
must be able to represent at least the range [-32767..32767]
1, meaning it must be at least 16 bits wide. It may be wider for two reasons:
The platform offers more value bits to store a wider range (e.g., x86 uses 32 bits to store integer values and 64 bits for long integers);
The platform uses padding bits that store something other than part of the value.
As an example of the latter, supposed you have a 9-bit platform with 18-bit words. In the case of the 18-bit word, two of the bits are padding bits and are not used to store part of the value - the type can still only store [-32767..32767]
, even though it's wider than 16 bits.
The <stdint.h>
header does define integer types with specific, fixed sizes (16-bit, 32-bit), but they may not be available everywhere.
[-32768..32767]
.
Upvotes: 0
Reputation: 31419
The standard is by definition correct, and the way you interpret it is correct. The sizes of some types may vary. The standard only states the minimum width of these types. Usually (but not necessarily) the type int
has the same width as the target processor.
This goes back to the old days where performance was a very important aspect. Se whenever you used an int
the compiler could choose the fastest type that still holds at least 16 bits.
Of course, this approach is not very good today. It's just something we have to live with. And yes, it can break code. So if you want to write fully portable code, use the types defined in stdint.h
like int32_t
and such instead. Or to the very least, never use int
if you expect the variable to hold a number not in the range [−32,767; 32,767]
.
Upvotes: 3
Reputation: 134048
On my computer long is 64 bits in Linux.
Windows is the only major platform that uses the 32-bit longs in 64-bit mode, exactly because of the false assumptions being widespread in the existing code. This made it difficult to change the size of long on Windows, hence on 64-bit x86 processors longs are still 32 bits in Windows to keep all sorts of existing code and definitions compatible.
Upvotes: 5