这些结构,align1
和 align2
, 包含相同的数据,但 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.b2
到 nested
内被认为是填充的内容无论您对此做什么,它都可能与以下要求相冲突:在写入和读取 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/