c++ - 是否有一种巧妙的方法可以避免在 C++ 中使用嵌套类进行额外填充?

标签 c++ padding compiler-optimization inner-classes memory-alignment

这些结构,align1align2 , 包含相同的数据,但 align1由于嵌套布局,有更多的填充。
如何获得 align2 的内存节省对齐同时也使用嵌套结构,如 align1 ?

int main() {
    struct align1 {
        struct {
            double d;    // 8 bytes
            bool b1;    //+1 byte (+ 7 bytes padding) = 16 bytes
        } subStruct;
        bool b2;        //+1 byte (+ 7 bytes padding) = 24 bytes
    };
    struct align2 {
        double d;        // 8 bytes
        bool b1, b2;    //+2 byte (+ 6 bytes padding) = 16 bytes
    };

    std::cout << "align1: " << sizeof(align1) << " bytes\n";    // 24 bytes
    std::cout << "align2: " << sizeof(align2) << " bytes\n";    // 16 bytes

    return 0;
}
嵌套subStruct struct 是必需的,因为它将在外部声明/定义。我正在使用 C++17 和 Visual Studio 2017。
生成的代码可能很脏或看起来很糟糕。我只是不希望它稍后向我抛出随机错误或在更改配置时中断。

最佳答案

我明确地依赖于提出“脏或难看”的代码的许可......任何东西。为了更清楚,我只提供一个想法。你需要测试自己并自己承担责任。我认为这个问题明确允许未经测试的代码。
使用此代码:

typedef union
{
    struct
    {
        double d;   // 8 bytes
        bool b1;    //+1 byte (+ 7 bytes padding) = 16 bytes
    } nested;
    struct
    {
        double d;       // 8 bytes
        bool b1, b2;    //+2 byte (+ 6 bytes padding) = 16 bytes
    } packed;
} t_both;
我希望具有以下属性/功能:
  • 包含在其他地方可能被类型定义的子结构(可以从包含的头文件中使用)
  • 子结构可作为 XXX.nested.d 访问和 XXX.nested.b1
  • 在与 XXX.packed 相同的地址
  • 访问 XXX.packed.b2nested 内被认为是填充的内容
  • 两个子结构的总大小相同,我希望这意味着即使制作数组也可以

  • 无论您对此做什么,它都可能与以下要求相冲突:在写入和读取 union 时,所有读取访问必须与最近一次写入的 union 部分相同。因此,不允许写一个读另一个。这就是我认为这个代码提案不清楚的地方。也就是说,我经常在已明确测试相应构造的环境中使用这种 union 。
    为了说明这里是一个功能相同但同样不干净的版本,它更好地说明了子结构可以在其他地方进行类型化:
    
    /* Inside an included header "whatever.h" : */
    typedef struct
    {
        double d;   // 8 bytes
        bool b1;    //+1 byte (+ 7 bytes padding) = 16 bytes
    } t_ExternDefedStruct;
    
    /* Content of including file */
    
    #include "whatever.h"
    
    typedef union
    {
        t_ExternDefedStruct nested;
        struct
        {
            double d;       // 8 bytes
            bool b1, b2;    //+2 byte (+ 6 bytes padding) = 16 bytes
        } packed;
    } t_both;
    

    关于c++ - 是否有一种巧妙的方法可以避免在 C++ 中使用嵌套类进行额外填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64647286/

    相关文章:

    c - 使用指向第一个成员的指针调用 free 是否有效?

    带有边框框大小和一些填充的 jQuery 弹跳效果

    compiler-construction - 为什么支持预编译头的编译器通常只允许一个?

    objective-c - 添加 Bridging-Header.h 后 Swift 编译器优化 -O 不起作用

    c - 编译器如何处理错位?

    c++ - 在opencv中将2张图像与透明蒙版结合起来

    c++ - 使用静态链接声明静态成员

    c++ - 强制非类函数存在?

    c++ - 如何从头开始在 Xcode 4 上构建 C++ 项目——链接现有的和新的外部库

    html - 无法正确镜像 div