我为一家使用大型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 ++项目,这是常见的做法和/或良好做法吗?是否有任何一般性(一般意义,非特定应用)原因使用这种做法是必需的还是有利的?
答案 0 :(得分:7)
是的,这是一种常见做法。我不能说这是好事还是坏事,因为它取决于。
当然,在做这件事时你必须要小心,因为将来某个时候你可能会用完保留的字段,通常是在你从未想过的地方。
答案 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
};