c++ - 对应该在 C++ 中保存结构的缓冲区使用右对齐

标签 c++ struct alignment

假设我们有一些结构,比如说

struct S
{
  double a, b;
  ~S(); // S doesn't have to be POD
};

这样的结构通常应具有 8 对齐,因为其最大包含类型的大小为 8。

现在假设我们要声明一个占位符结构来保存 S 的值:

struct Placeholder
{
  char bytes[ sizeof( S ) ];
};

现在我们想把它放在另一个类中:

class User
{
  char someChar;
  Placeholder holder;
public:
  // Don't mind that this is hacky -- this just shows a possible use but
  // that's not the point of the question
  User() { new ( holder.bytes ) S; }
  ~User() {  ( ( S * )( holder.bytes ) )->~S(); }
};

问题是,Placeholder 现在在 User 中对齐不正确。由于编译器知道 Placeholder 是由字符组成的,而不是 double ,因此它通常使用 1 的对齐方式。

有没有办法声明Placeholder 的对齐方式与C++03 中的S 对齐?请注意,S 不是 POD 类型。我也知道 C++11 有 alignas,但这还不是普遍可用的,所以如果可能的话我宁愿不要指望它。

更新:澄清一下,这应该适用于任何 S - 我们不知道它包含什么。

最佳答案

您可以使用union,如果您可以使S符合成为union*成员的要求。

union 保证为其最大的成员提供足够的存储空间,并为其最严格的成员对齐。因此,如果我们使占位符成为原始字符缓冲区和实际存储在那里的所有类型的并集,您将拥有足够的大小和正确的对齐方式。

除了存储本身,我们永远不会访问 union 的成员。它们仅用于对齐。

沿着这些线的东西:

struct Placeholder
{
  union
  {
    char bytes [sizeof(S)];
    double alignDouble;
  };
};

  • 成为 union 成员的要求”: union 的成员不能拥有:非平凡的构造函数、非平凡的复制构造函数、非平凡的析构函数, 非平凡的复制赋值运算符。

关于c++ - 对应该在 C++ 中保存结构的缓冲区使用右对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17859273/

相关文章:

c - 声明另一个函数时使用函数名和昵称(由 typedef 制成)有什么区别?

CSS:更改 HREF 中的垂直文本位置

c++ - Visual Studio 2010,可以简单地包含一个新类来触发发布构建错误吗?

c++ - 在 C++ 中重载 [][] 运算符

c++ - 模板化类方法定义语法

css - wordpress主题中的中心 Logo 文本(greenchilli)

html - 悬停在图像上时使 h2 文本下划线

c++ - 输出文件流的 '<<'和 'put()'之间的区别

c++ - 使用对象指针时访问冲突读取

c++ - 在 C++ 中使用 .find() 和 struct 作为映射中的键