可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Hm... why is it that, when I print sizeof(struct MyStruct), it outputs 3 (instead of 2) for this code?
#pragma pack(push, 1) struct MyStruct { unsigned char a : 6; union { struct { unsigned int b : 9; }; }; }; #pragma pack(pop)
In case it matters, I'm running MinGW GCC 4.5.0 on Windows 7 x64, but honestly, the result is weird enough for me that I don't think the compiler and the OS matter too much here. :\
回答1:
You can't have the field starting at an address that is not byte aligned. You're expecting:
6 bits + 9 bits -> 15 bits -> 2 bytes
but what you're getting is:
6 bits -> 1 byte 9 bits -> 2 bytes total -> 3 bytes
The data is being stored as:
| 1 byte | 2 byte |3 byte | aaaaaaXX bbbbbbbb bXXXXX
when you were expecting:
| 1 byte | 2 byte | aaaaaabb bbbbbbbX
edit: To clarify based on the comments below:
The union (and the containing struct) must be byte aligned. It doesn't matter that the contents are only 9 bits, the union/struct itself is a full 16 bits. Notice that you cannot do the following:
struct MyStruct { unsigned char a : 6; union { struct { unsigned int b : 9; } c:9; } d:9; };
As C won't let you specify the entire struct's bit-size.
回答2:
Adding to the answer given by @nss -- my apologies, this would've been a comment if comments weren't so limited on formatting:
#include <stdlib.h> struct Test { unsigned short x : 6; unsigned short y : 1; unsigned short z; }; int main( int argc, char *argv[] ) { printf( "sizeof( Test ) = %d\n", sizeof( struct Test ) ); return 0; }
It prints '4' for the size. I tested with gcc, g++, and Sun Studio's CC and cc.
Not that I recommend doing what you're attempting to do, but you could probably do what you're attempting to do with a union. I've seen (but not written myself) code that looked like this:
struct Test { unsigned short x1 : 6; unsigned short x2 : 3; : 1; // unused unsigned short x3 : 4; // ... };
I might have the syntax slightly wrong there ... but I don't think so.
Point being: create two separate structs (or a struct and a union) with the layout you were going for, then insert some dummy members where they should overlap, and union those together.