簡體   English   中英

對於應該在C ++中保存結構的緩沖區,使用正確的對齊方式

[英]Use the right alignment for a buffer which is supposed to hold a struct in C++

假設我們有一些結構,比方說

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由字符而不是雙字符組成,因此它通常使用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 s不能有:非平凡的構造函數,不平凡的拷貝構造函數,非平凡的析構函數,非平凡的拷貝賦值運算符。

我相信boost::aligned_storage可能正是你想要的。 它使用聯合技巧,使您的類型無關緊要(您只需使用sizeof(YourType)告訴它如何對齊)以確保正確對齊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM