【问题标题】:C++ Struct - Define Minimum SizeC++ 结构 - 定义最小尺寸
【发布时间】:2013-05-31 12:35:10
【问题描述】:

是否有自动将结构填充到最小大小的 C++(或 MSVC)方法?例如,想象下面的伪代码:

#pragma pad(256) // bytes
struct SETUPDATA {
  int var1;
  double var2;
};

where sizeof(SETUPDATA) = 256 bytes

这里的目标是,在开发过程中,这个结构的成员可以在不改变运行时的足迹大小的情况下改变。

【问题讨论】:

  • 比尔盖茨曾经说过 640k 就够了... :)
  • 您可以尝试使用char[256] 将其包装在一个联合中。
  • Union 不会阻止大小变大,使用 static_assert() 验证它没有改变。
  • 您不会希望在这种情况下使用 int。大小不保证为 32 位。您想使用 int32_t
  • 我认为这是一个想法,改变成员而不改变运行时的足迹?这只是……一个坏主意。

标签: c++ visual-c++ memory-management


【解决方案1】:

你可以使用联合

struct SETUPDATA {
    union { struct your_data; char [256]; }
}

或类似的东西。这确保它至少为 256,但前提是 your_data 不大。

您还可以在编译器检查之后添加一个简单的断言assert(sizeof(struct SETUPDATA) == 256)

【讨论】:

  • 这应该可以播放 - 甚至 VS2008 似乎也允许我使用匿名结构来简化事情。
【解决方案2】:

一种方法是从您的“真实”结构继承并使用sizeof() 来构成填充结构,例如:

struct blah_real
{
    int a;
};
struct blah : public blah_real
{
private:
    char _pad[256 - sizeof(blah_real)];
};

您可以使用#ifdef DEBUG 仅在调试版本中执行此操作,并在发布版本中使用真实结构。

【讨论】:

    【解决方案3】:

    您首先要问自己的是为什么您的应用程序关心struct 大小是否发生变化。这表明对未来变化的脆弱性,并且通过允许应用程序在面对结构大小变化时无缝工作,您的设计可能会得到更好的服务。

    也许您正在尝试直接序列化数据并且不想面对格式的更改,但在这种情况下,您已经将自己绑定到结构的一种特定表示中记忆。例如,支持由于编译器升级或选项而导致的内置类型成员之一的大小变化。

    但是假设你真的想要这样做。

    只需将数据包装在一个 impl 中并填充真正的结构:

    struct SetupData
    {
        struct Impl
        {
            int var1;
            double var2;
        };
    
        Impl impl_;
        unsigned char pad_[256 - sizeof(Impl)];
    };
    

    【讨论】:

    • 我不认为编译器不会在impl_pad_ 之间插入填充,使结构大于256 字节。如果 sizeof(Impl) 恰好是 256 个字节,它也可能会失败,因为该语言不允许使用 0 长度数组。
    • 感谢您的解决方案。在这种情况下,核心应用程序是第 3 方,我只是在编写插件模块。无论好坏,应用程序都为加载/保存链使用结构副本(嵌入式应用程序的优先级与桌面应用程序不同)。因此,每次我修改结构的大小时,都会使保存的数据无法加载。
    • 太棒了,一条评论秒猜出提问者为什么想做某事!有充分的理由将结构填充到一定大小,例如避免错误共享缓存行。
    猜你喜欢
    • 1970-01-01
    • 2016-07-07
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 2012-01-03
    相关资源
    最近更新 更多