c++ - 准确计算编译器在结构中添加的填充

标签 c++ c

我目前有以下结构

struct foo {
    u32 bar;
    u8 baz[1];
}

由于填充,sizeof(struct foo) 变成了 8。

如果我想要准确的结构大小(在本例中为 5),我将如何以“可扩展”的方式进行计算(即不执行类似 sizeof(foo.bar) + sizeof (foo.baz))?

最佳答案

在标准 C 中,如果不在源代码中列出结构体成员的大小,就无法计算它们的总大小(这可以通过预处理器功能的帮助或使用其他代码[编译和执行]来完成在最终代码的编译时]生成最终代码)。这是因为标准 C 没有提供任何方法来迭代结构体的成员或以其他方式在不使用其成员名称的情况下检查其组成。

我会对 C++ 做出同样的主张,只不过模板之类的东西可能会发生一些可怕的黑客攻击。我倾向于认为这是不可能的,但我还没有检查最新 C++ 标准中的所有新功能。

无论如何,计算总大小都不足以实现序列化和反序列化成员的既定目的(即将成员转换为网络包中的字节,反之亦然),因为您仍然需要单独转换成员,不仅仅是知道他们的总尺寸。

实现目标的选项包括:

  • 使用特定于实现的功能来打包结构,使其不包含填充。然后您可以写入和读取结构体的字节以执行序列化和反序列化。您仍然需要确保发送和接收系统之间的类型匹配(相同宽度的整数、相同格式的浮点值、相同的字符集编码等等)。
  • 编写代码以在运行时处理所需类型。它将采用某种格式(例如类型列表)对结构进行描述,并且每种类型都有案例。每个案例都将包含该类型的编译时代码(例如,sizeof(float)),但代码将在运行时在案例之间分派(dispatch)。因此,您需要按照此代码使用的格式准备结构的描述。

关于c++ - 准确计算编译器在结构中添加的填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21150049/

相关文章:

c++ - 在进入 main() 之前我遇到段错误

c++ - 将午夜后的毫秒数转换为时间对象

c++ - 为什么STL中没有std::find_not?

c++ - BuildCommDCB 实际上做了什么?

c - __attribute__((force)) 有什么作用?

c++ - 如何检查注册表中是否未设置(默认)值

c++ - 尝试获取 C++ switch 语句来识别空格、制表符等

c - FltRegisterFilter 不工作

c - C 中未定义的行为

c - 复杂函数定义中的参数范围