打包的bitfield struct的赋值给出了错误的值

时间:2015-03-31 15:51:18

标签: c

我有一个16位的压缩结构:

#pragma pack(1)

typedef unsigned int uint;
typedef unsigned short ushort;

typedef struct Color Color;
struct Color
{
    uint r : 5;
    uint g : 5;
    uint b : 5;
    uint _ : 1;
};

我已确认

&(((Color*)0x06000000)[x]) == &(((ushort*)0x06000000)[x])

对于x的各种值。但是,在这段代码中,这两行给出了不同的结果。

void write_pixel (uint x, uint y, Color color)
{
    #if 0
    ((Color*)0x06000000)[x+y*240] = color;
    #else
     ((ushort*)0x06000000)[x+y*240] = ((ushort*)&color)[0];
    #endif
}

第二个选项是正确的。

可能是什么原因?

记。我正在为GBA模拟器编译所以没有调试器或printf,只是通过绿色/红色像素的是/否语句。

1 个答案:

答案 0 :(得分:2)

问题是从参数列表中看到的值(由于参数的提升)将作为无符号整数(32位)。然后不正确的行试图将32位无符号整数复制为16位短整数。

通常这会起作用但是pragma会修改16bit Color在提升参数中的放置方式和/或代码引用16位Color的方式。

While packed values are (normally) not promoted,
if there is no prototype for the called function
then all parameters are assumed to 'int' 
so the code assumes the data is (sizeof int) bytes long (4 bytes)
and the assignment takes the last 2 bytes
of that 4 byte value rather than the first 2 bytes.