Page 1 of 1

sizeof int and long

Posted: Sun Apr 06, 2008 4:21 am
by AlfaOmega08
Some books says that sizeof(int) = 2, and sizeof(long) = 4.
I've always known that sizeof(int) = sizeof(long) = 4...

Also gcc agree with my opinion...

So, what's the TRUE size of an int?

Posted: Sun Apr 06, 2008 4:23 am
by Combuster
short answer: undefined :)
long answer: http://www.nirvani.net.nyud.net:8090/docs/ansi_c.pdf

Posted: Sun Apr 06, 2008 4:29 am
by AlfaOmega08
ops... wrong section

To be sure that i'm using a 4-byte type on any compiler can I:

typedef unsigned long dword

?

Posted: Sun Apr 06, 2008 5:10 am
by bluecode
please typedef one of the standard types: (u)int8/16/32/64_t, don't use yet another name (and even one that is not really defined in terms of size).

typedef unsigned long uint32_t;

will work on a 32bit x86 gcc. It won't however for 64bit x86 gcc (unsigned long will be 64bit there, unsigned int however is 32bit there).

Posted: Sun Apr 06, 2008 7:55 am
by Laksen
Doesn't stdint.h define all those so they are the same on all platforms?

Posted: Sun Apr 06, 2008 8:45 am
by Brynet-Inc
stdint.h helps make clearer and more portable code... and as bluecode said, long is a 64-bit type on AMD64, but it's 32-bit on x86 systems, int can even be a 16-bit type on some architectures.

Quite a few people have been making their own types for this purpose, but it's probably better to use the "standards".

http://www.opengroup.org/onlinepubs/009 ... int.h.html

Right, so a partial stdint.h could look like this:

Code: Select all

#if defined(__i386__) || defined(__amd64__)
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
#if defined(__i386__)
typedef long int32_t;
typedef unsigned long uint32_t;
#elif defined(__amd64__)
typedef int int32_t;
typedef unsigned int uint32_t;
#endif
typedef long long int64_t;
typedef unsigned long long uint64_t;
#endif
That way, when you decide to port to an additional architecture.. you can make changes accordingly. :)

Posted: Sun Apr 06, 2008 9:11 am
by Krox
and make sure you've got some assert(sizeof(uint32_t) == 4) and alike somewhere...

Before I forget, the following will work at least on x86 and x64, AFAIK. Not standard, but working without those __X__ macros...

Code: Select all

typedef unsigned char uint8;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
[/code]

Posted: Tue Apr 08, 2008 1:59 am
by Solar

Code: Select all

Before I forget, the following will work at least on x86 and x64, AFAIK. Not standard, but working without those __X__ macros... 
Sizes of short, int, and long are up to the compiler and the platform specs. Your code might work on GCC but break on Borland. Or work on Watcom but break on ICC.

Do not assume.

The compilers do you a courtesy and export intX_t and uintX_t in <stdint.h>. Use those. Don't try to come up with your own clever typedefs. They will break. Sooner or later.

Posted: Tue Apr 08, 2008 7:25 am
by Zenith
The compilers do you a courtesy and export intX_t and uintX_t in <stdint.h>. Use those. Don't try to come up with your own clever typedefs. They will break. Sooner or later.
Yeah, I was going to try that but sadly, I couldn't figure out how to get GCC to include the standard freestanding headers!

Maybe that's because I'm using the cross-compiler from the tutorial (without-headers)?

But what'll happen when I do compile it with newlib headers - there's actually no actual code involved in the freestanding headers other than typedefs/macros, right?

Posted: Tue Apr 08, 2008 8:23 pm
by pcmattman
Copy & paste the stdint.h from your system include directory?

Posted: Wed Apr 09, 2008 1:02 am
by Solar
No, don't copy from your system include directory. GCC should have built a stdint.h during the cross-compiler setup; I can't check ATM where it's located exactly, but use that, not your system's one (configs may differ).

Posted: Wed Apr 09, 2008 1:15 am
by pcmattman
I've found the include directory for the cross-compiler build in $PREFIX/lib/gcc/$TARGET/<version>/include, but mine doesn't have a stdint.h (it has things like syslimits.h, stddef.h, among other files).

On the other hand, if you do a newlib port you get a stock stdint.h that newlib provides that works with minor changes out of the box.

Posted: Wed Apr 09, 2008 5:35 am
by bluecode
Solar wrote:No, don't copy from your system include directory. GCC should have built a stdint.h during the cross-compiler setup; I can't check ATM where it's located exactly, but use that, not your system's one (configs may differ).
The gcc crosscompiler does not come with a stdint.h. At least none of my four gcc crosscompiler does come with one.But it does come with: float.h iso646.h limits.h stdarg.h stdbool.h stddef.h

Posted: Thu Apr 10, 2008 12:38 am
by Solar
Ah well... the safe bet, then, would be to construct your own stdint.h using the values found in limits.h.

I will have to have a closer look at this once things get back to normal. (Our household is still mostly packed up in boxes after relocation.)