结构填料。有没有一种自动的方法来做到这一点?

qqi*_*row 5 c c++ memory struct data-structures

问题:有没有一种自动进行结构打包的方法?

背景

结构打包对于减少某些基础数据的内存成本非常有用。基本上,这是通过对内部数据重新排序来实现最小内存成本的技巧。我的问题是有没有一种自动方法可以做到这一点?例如,我这里有一个struct Foo。(假设32位)

struct Foo {     
  char flag;
  char* p;
  short number;
};
Run Code Online (Sandbox Code Playgroud)

经过自动检查(无论是否是脚本,无论是否是本机),我应该获得 Foo 的内存优化版本,即:

struct Foo {
  char* p;
  short number;  
  char flag;     
};
Run Code Online (Sandbox Code Playgroud)

这只是一个玩具示例。考虑下面更困难的情况,手动重新排序将是一项相当艰巨的工作。

  1. 结构具有依赖结构:

    struct Foo {
      char* p;
      short number;
      MoreFoo more_foo // How to deal with this?
      char flag;     
    };
    
    Run Code Online (Sandbox Code Playgroud)
  2. struct 位于遗留代码中,并且您不熟悉代码库。

  3. 您希望代码是跨平台的。遗憾的是,这个技巧依赖于编译器。

我不考虑使用“packed”属性,因为它会导致一些性能问题。

__attribute__((packed)) 会影响程序的性能吗?

Ben*_*igt 3

在 C++03 中,您可以通过将每个成员放在单独的访问部分中来授予编译器重新排序成员的权限,例如:

struct Foo
{
public:
  char* p;
public:
  short number;
public:
  MoreFoo more_foo;
public:
  char flag;     
};
Run Code Online (Sandbox Code Playgroud)

我不知道特定的编译器是否使用这种额外的灵活性。

这不会改变声明顺序,它只是将内存顺序与声明顺序取消链接,因此 PaulMcKenzie 对初始化顺序的担忧不适用。(而且我认为他夸大了这种担忧;成员初始化器首先引用其他子对象的情况非常罕见)

其工作原理是因为它会导致以下规则(9.2)中的规则不再有效:

分配未插入访问说明符声明的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。 由访问说明符分隔的非静态数据成员的分配顺序未指定(11.1)。实现对齐要求可能会导致两个相邻成员不能立即分配;管理虚拟函数 (10.3) 和虚拟基类 (10.1) 的空间要求也可能如此。

另外,这在 C++11 中是否仍然有效也是值得怀疑的,因为措辞从“没有中间访问说明符”更改为“具有相同的访问控制”:

分配具有相同访问控制(第 11 条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定(第 11 条)。实现对齐要求可能会导致两个相邻成员不能立即分配;管理虚拟函数 (10.3) 和虚拟基类 (10.1) 的空间要求也可能如此。