C ++备用数据以保持对象大小相同?

时间:2017-09-21 12:32:59

标签: c++ memory

我为一家使用大型C ++项目的公司工作,以自动化制造流程,在查看C ++源代码的修订历史时,我注意到以下特殊行为。

下面显示了软件不同版本中此行为的简化示例。

软件修订版1:

struct Foo
{
    int x;
    int reserve[20]; // unused
};

软件修订版2:

struct Foo
{
    int x;
    int y[2];
    int reserve[18]; // unused
};

软件修订版3:

struct Foo
{
    int x;
    int y[2];
    int z[5];
    int reserve[13]; // unused
};

很明显,未使用的reserve数组就是为了确保创建的结构的任何实例总是占用相同数量的内存,无论软件的哪个版本正在运行。

我的问题是:对于大型C ++项目,这是常见的做法和/或良好做法吗?是否有任何一般性(一般意义,非特定应用)原因使用这种做法是必需的还是有利的?

3 个答案:

答案 0 :(得分:7)

是的,这是一种常见做法。我不能说这是好事还是坏事,因为它取决于。

  • 如果您的结构代表某种类型的数据包或数据 某些规范中的字段,通常有保留字段。 有时,当开发新版本的规范时,那些 保留字段用于有意义的事情。我一起工作过 PCIe规范符合性并且这种情况发生了几次。
  • 如果您希望能够为您的网络添加一些新数据 数据包,但您希望旧版客户端能够读取它 数据包好像是旧版本,这可能是合理的 解决方案有时候。

当然,在做这件事时你必须要小心,因为将来某个时候你可能会用完保留的字段,通常是在你从未想过的地方。

答案 1 :(得分:1)

如果您定义的结构是通过网络发送的,并且您不想实现某些网络协议协商,则可以在新产品版本中使用包含更多字段的struct,旧版本仍然可以接收此类结构(如大小不会改变)。它只会忽略它不知道的部分(将其视为reserve的一部分)。

答案 2 :(得分:0)

为了它的价值...我终于(在发布此问题后一年多)找到了确切原因:

程序将此struct存储在共享内存文件中。

使该结构保持相同格式的目的是保留该结构的确切内存位置,以便共享内存的任何过去和将来的事件仍将以相同的方式工作。

char用作一字节的“缓冲区”,以使结构始终保持相同大小。然后根据所使用的数据类型减少reserve数组。

我还发现创建了第二个reserve数组(例如reserve2),以使“跳转”总是以4字节的跳转发生。请参见下面的可视化说明。该结构总会增加100个字节。

修订版1:

struct Foo
{
    int x;             //  4 bytes
    char reserve[96];  // 96 bytes
};

修订版2:

struct Foo
{
    int x;             //  4 bytes
    short y;           //  2 bytes
    char reserve[94];  // 94 bytes
};

修订版3:

struct Foo
{
    int x;             //  4 bytes
    short y;           //  2 bytes
    short reserve2;    //  2 bytes (added so that the "jump" is still 4 bytes)
    int z;             //  4 bytes
    char reserve[88];  // 88 bytes
};