关于c ++:结构包装。

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

问题:有没有一个自动的方式来做结构包装?

背景:

结构打包对于降低某些基础数据的存储成本非常有用。基本上,这是通过重新排序内部数据来实现最小内存成本的技巧。我的问题是有自动的方法吗?例如,我这里有一个结构foo。(假设32位)

1
2
3
4
5
struct Foo {    
  char flag;
  char* p;
  short number;
};

在自动检查之后(不管是不是脚本,本机的还是非本机的),我应该得到一个foo的内存优化版本,它是:

1
2
3
4
5
struct Foo {
  char* p;
  short number;  
  char flag;    
};

这只是一个玩具的例子。考虑到下面更困难的情况,这将是一个相当大的手工重新排序工作。

  • 结构具有依赖结构:

    1
    2
    3
    4
    5
    6
    struct Foo {
      char* p;
      short number;
      MoreFoo more_foo // How to deal with this?
      char flag;    
    };
  • 结构位于旧代码中,您不熟悉代码库。

  • 您希望代码是跨平台的。不幸的是,这个技巧依赖于编译器。
  • 我不考虑使用"packed"属性,因为它会导致一些性能问题。

    _uuu属性_uuuuu((packed))能否影响程序的性能?


    在C++ 03中,您可以通过将每个成员放置在一个单独的访问段中,给编译器重新排序成员的权限,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct Foo
    {
    public:
      char* p;
    public:
      short number;
    public:
      MoreFoo more_foo;
    public:
      char flag;    
    };

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

    这不会更改声明顺序,它只是将内存顺序与声明顺序断开链接,因此PaulMcKenzie对初始化顺序的关注不适用。(我认为他夸大了这种关注;成员初始值设定项一开始很少提及其他子对象)

    其工作方式是因为它导致以下规则(从9.2)不再有效:

    Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).

    同样,这是否在C++ 11中仍然存在疑问,因为措辞从"没有中间访问指示符"改为"具有相同的访问控制":

    Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (Clause 11). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).


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

    不幸的是,鉴于此,只能手动重新订购结构。您可能需要找到结构的所有属性的大小,因此:

    1
    2
    3
    4
    5
    6
    7
    8
    printf ("Size of char is %d
    "
    , sizeof (char));
    printf ("Size of char* is %d
    "
    , sizeof (char*));
    printf ("Size of short is %d
    "
    , sizeof (short));
    printf ("Size of MoreFoo is %d
    "
    , sizeof (MoreFoo more_foo));

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