结构填料.有没有自动的方法可以做到这一点

Structure Packing. Is there a automatic way to do it?

本文关键字:这一点 方法 有没有 结构      更新时间:2023-10-16

问题:有没有一种自动方法可以进行结构包装?

背景

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

struct Foo {     
  char flag;
  char* p;
  short number;
};

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

struct Foo {
  char* p;
  short number;  
  char flag;     
};

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

    结构
  1. 具有依赖结构:

    struct Foo {
      char* p;
      short number;
      MoreFoo more_foo // How to deal with this?
      char flag;     
    };
    
  2. struct 位于旧代码中,您不熟悉代码库。

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

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

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

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

struct Foo
{
public:
  char* p;
public:
  short number;
public:
  MoreFoo more_foo;
public:
  char flag;     
};
我不知道

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

这不会更改声明顺序,它只是取消内存顺序与声明顺序的链接,因此 PaulMcKenzie 对初始化顺序的担忧不适用。 (我认为他夸大了这种担忧;成员初始值设定项很少首先引用其他子对象)

这样做的方式是因为它会导致以下规则(从 9.2) 开始不再有效:

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

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

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

在 C 编程中,结构的自动优化是不可能的,因为这会违背它的设计方式。C允许对硬件进行低级访问,实际上,它只比汇编语言高出一步。它旨在创建控制硬件的依赖代码。

鉴于此,不幸的是,您只能手动重新排序结构。您可能需要查找所有结构属性的大小,如下所示:

printf ("Size of char is %dn", sizeof (char));
printf ("Size of char* is %dn", sizeof (char*));
printf ("Size of short is %dn", sizeof (short));
printf ("Size of MoreFoo is %dn", sizeof (MoreFoo more_foo));

然后根据这些值对结构进行排序。

相关文章: