保证的ANSI C结构大小

vu8f3i0k  于 2023-03-22  发布在  其他
关注(0)|答案(2)|浏览(118)

我想在不使用任何外部库的情况下,仅使用标准C来读取、编辑和写入bmp文件。
如果我理解正确的话,字节正确对齐以匹配bmp文件格式是很重要的。
然而,我想我也在互联网上的某个地方读到,编译器被允许用额外的字节填充struct,所以我不能总是确切地知道我的结构体占用了多少字节,甚至不能确定成员在结构体中是如何对齐的。
我如何使用标准C解决这个问题?是否有语法要求编译器确保我的结构体看起来完全符合我指定的方式?

q8l4jmvw

q8l4jmvw1#

我如何使用标准C解决这个问题?是否有语法要求编译器确保我的结构体看起来完全符合我指定的方式?
C标准没有提供一个标准的方法来控制结构布局。所以,如果你坚持只使用标准指定的内容,你就不能使用结构来处理Windows位图文件。
要使用标准C来解决这个问题,你需要自己写/读字节数组并序列化/反序列化它们。

46qrfjad

46qrfjad2#

正如Kninnug在注解中所说,BMP格式被设计为与C结构类型兼容。C编译器可以自由地在任何两个结构成员之间或最后一个成员之后插入尽可能多的填充,无论出于什么原因,但在真实的生活中,编译器只在对齐所需的地方插入填充,并且通常符合平台的书面ABI。
您可以使用offsetof宏和sizeof操作符来 test,但不能指定结构类型的布局--这可能已经足够满足您的目的了。
例如,如果您希望结构符合外部强加的布局,该布局由一个32位无符号整数、一个16位无符号整数和两个8位无符号整数组成,按此顺序分配,总共64位,则可以编写如下代码:

#include <stdint.h>
#include <stddef.h>
#include <assert.h>

struct s {
    uint32_t a;
    uint16_t b;
    uint8_t c;
    uint8_t d;
};

void test_layout(void) {
    assert(offsetof(struct s, a) == 0);
    assert(offsetof(struct s, b) == 4);
    assert(offsetof(struct s, c) == 6);
    assert(offsetof(struct s, d) == 7);
    assert(sizeof (struct s) == 8);
}

程序启动时调用test_layout()函数;如果你的程序在那之后仍然存在,你可以确信布局是正确的。
好吧,差不多--测试字节顺序作为练习。

相关问题