读取结构体大小时出现问题

5
如果我调试以下代码,我会看到size的值为12(与预期相符)。
#include <cstdint>

int main(int argc, char *argv[])
{
    typedef struct __attribute__((__packed__))  { int8_t value; } time;

    typedef struct __attribute__((__packed__))  {
        uint8_t msg[8];
//        time t1;
        uint32_t count;
    } theStruct;

    theStruct s;
    int size = sizeof(s);

    return 0;
}
有趣的是,在“时间t1;”删除注释后,size的值变为16。我原本期望的是13。 我知道(或多或少)这可以通过数据结构填充来解释... 但是,有没有什么方法可以避免这个问题? 该怎么做才能读取size=13

4
在我的测试中(使用g++ 4.8.4),在去除注释后,得到的大小是13。你确定你正确地进行了测试吗? - Evan Teran
3
"sizeof(time)" 给出的是什么? - Eugene Sh.
另外,为什么time是一个结构体?如果它只有一个成员,那是为了语法而存在吗? - Iharob Al Asimi
1
如果您这样做,会发生什么情况 #pragma pack(1) typedef struct { int8_t value; } time; typedef struct { int8_t t1; uint32_t count; uint8_t msg[8]; } theStruct; #pragma pack(1) - Iharob Al Asimi
@KcFnMi,__attribute__ 这个东西是 gcc 特定的,可能会在 MinGW 上引起问题。 - Iharob Al Asimi
显示剩余11条评论
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
4

1
这就是我认为它与操作系统有关的原因,因为在我的Linux系统上没有发生这种情况。这也是为什么我在评论中提出了建议,如果您愿意,可以将其附加到此答案中。 - Iharob Al Asimi

0

这显然是一个对齐问题,意味着它与语言本身无关,而与底层平台有关。

如果平台知道(或认为)int32_t需要4字节的对齐,那么它应该在time后添加3个字节的填充。

无论如何,__attribute__((__packed__))不是标准C,只能被gcc解释。更糟糕的是,它会导致程序不可移植:根据另一个问题的答案所述,它会在Sparc架构上由于int32_t未对齐而导致总线错误。

我知道x86(及其衍生品)架构现在是最常见的,但其他架构仍可能存在...

(*) 根据GCC __attribute__ ((__packed__))的Visual C++等效项,MSVC的等效项是#pragma pack(push, 1)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,