Back in 2000, I came across this Advogato article about proper coding guidelines for the coming wave of 64-bit machines. The most interesting part, I thought, was comment #2 (“C is portable, if you let it be”) which offers some very sane guidelines for declaring variable types to just allow the compiler to do its job effectively. This is why I usually just declare int’s for numbers rather than uint32_t’s everywhere. There is often no reason to try to force particular types.
Don’t think that you’re saving space by declaring a uint8_t instead of an int– chances are that you aren’t. I’ve disassembled enough C code compiled into 32-bit x86 machine code to know that a compiler will usually allocate 32 bits for that 8-bit variable. In fact, here is a small piece of code to drive the point home:
stack.c:
Compile with: gcc -Wall stack.c -o stack
Disassemble with: objdump -d -Mintel stack
Key parts:
080483a0 < main >: 80483a0: 55 push ebp 80483a1: 89 e5 mov ebp,esp 80483a3: 83 ec 08 sub esp,0x8 80483a6: 83 e4 f0 and esp,0xfffffff0 80483a9: b8 00 00 00 00 mov eax,0x0 80483ae: 29 c4 sub esp,eax 80483b0: e8 07 ff ff ff call 80482bc < random @plt > 80483b5: 88 45 ff mov BYTE PTR [ebp-1],al 80483b8: 66 0f be 45 ff movsx ax,BYTE PTR [ebp-1] 80483bd: 40 inc eax 80483be: 66 89 45 fc mov WORD PTR [ebp-4],ax
Notice that, despite strictly needing only 3 bytes of local variable storage, 8 bytes were allocated from the stack. 32-bit machines like the i386 really, really like dealing with 32-bit quantities.
> 32-bit machines like the i386 really, really like dealing with 32-bit quantities.
That’s the common rule for most CPUs. It’s always a good thing to use processor-native variable sizes.
You can do a similar thing with a structure….
struct test {
int a;
char b;
};
sizeof(struct test) = 8.