This is a subjective question: "Why does the specification say this?" But I will give him my chance.
Variables in functions usually have "automatic" storage, unlike one of the other durations (static duration, stream duration, and assigned duration).
In the structure, you explicitly define the memory layout of an object. But in a function, the compiler automatically allocates storage in some vague way to your variables. Here's the question: how many bytes does x occupy on the stack?
It can take up to 4 bytes, or it can take 8 or 12 or 0, or it can be pushed into three different registers at the same time, or on the stack and in the register, or it can get four places on the stack.
The fact is that the compiler performs the allocation for you. Since you are not stacking, you should not specify the width of the bits.
Expanded Discussion: Battlefields are actually a bit special. The specification states that adjacent bit fields are packed into the same memory block. Battle objects are not really objects.
You cannot sizeof() a bit field.
You cannot malloc() bit field.
You cannot &addressof the bit field.
You can do all these things with objects in C, but not with bit fields. Beatps are a special thing, created only for structures and nowhere else.
About int24_t (updated): It works with some architectures, but not with others. It is not even tolerated.
typedef struct { int x : 24 __attribute__((packed)); } int24_t;
On Linux, ELF / x64, OS X / x86, OS X / x64, sizeof(int24_t) == 3 . But on OS X / PowerPC, sizeof(int24_t) == 4 .
Note that the GCC code created to load int24_t is basically equivalent to this:
int result = (((char *) ptr)[0] << 16) | (((unsigned char *) ptr)[1] << 8) | ((unsigned char *)ptr)[2];
These are 9 x64 instructions, just for loading a single value.