禁用64位结构上的对齐

时间:2016-05-20 07:18:58

标签: c++ bit-manipulation

我正在尝试对齐我的结构,并使用位字段尽可能小。我必须将此数据发送回客户端,客户端将检查字段以设置一些数据成员。 结构的大小确实相同,但是当我设置成员时它根本不起作用。 这是一些示例代码:

#pragma pack(push, 1)
struct PW_INFO
{
    char hash[16]; //Does not matter
    uint32_t number; //Does not matter
    uint32_t salt_id : 30; //Position: 0 bits
    uint32_t enc_level : 7; //Position: 30 bits
    uint32_t delta : 27; //Position: 37 bits
}; //Total size: 28 bytes
#pragma pack(pop)

void int64shrl(uint64_t& base, uint32_t to_shift, uint32_t position)
{
    uint64_t res = static_cast<uint64_t>(to_shift);
    res = Int64ShllMod32(res, position);
    base |= res;
}

int32_t main()
{
    std::cout << "Size of PW_INFO: " << sizeof(PW_INFO) << "\n"; //Returns 28 as expected (16 + sizeof(uint32_t) + 8)
    PW_INFO pw = { "abc123", 0, 0, 0, 0 };
    pw.enc_level = 105;

    uint64_t base{ 0 };
    &base; //debug purposes
    int64shrl(base, 103, 30);

    return 0;
}

这里变得奇怪:设置“salt_id”字段(在位域中为30位)将在内存中产生以下结果:

0x003FFB8C  61 62 63 31 32 33 00 00  abc123..
0x003FFB94  00 00 00 00 00 00 00 00  ........
0x003FFB9C  00 00 00 00 00 00 00 00  ........
0x003FFBA4  69 00 00 00              i...
(Only the last 8 bytes are of concern since they represent the bit field.)

但是,Int64ShllMod32会返回正确的结果(远程客户端完美地覆盖它):

0x003FFB7C  00 00 00 c0 19 00 00 00  ...À....

我猜它与对齐有关,如果是这样,我怎么能完全摆脱它呢?即使大小正确,它也会尝试对齐它(#pragma指令建议的1字节边界)。

更多信息: 我使用Visual Studio 2015及其编译器。 我不是试图以不同的格式编写它们,我之所以要问这是因为我不想使用自己的格式。他们正在从64位位域读取,我无法访问源代码,但我看到很多对Int64ShrlMod32的调用(从我读到的,这是编译器在处理8字节结构时产生的)。 实际的位域从“salt_id”开始。 30 + 7 + 27 = 64位,我希望现在更清楚了。

0 个答案:

没有答案