确保std :: string上的正确对齐

时间:2013-06-27 09:12:52

标签: c++ visual-studio-2010 alignment stdstring

编译此标题:

// myheader.h

class MyClass {

    MyClass();
    ~MyClass();

    unsigned int mMyUint;
    bool bMyBool;
    std::string sMyString;
};

使用Visual Studio 2010 / W4(我被告知这样做),目标x64,给我以下warning C4121

'MyClass' : alignment of a member was sensitive to packing,指的是std::string sMyString所在的行。 official help of Microsoft建议使用#pragma pack(x),其中x为1,2,4依赖于其结构/类中使用的成员。

不,我想知道哪个对齐用于std :: string?我的想法是std :: string也不是编译器,也不是平台独立的。有没有办法解决这个问题,特别是考虑到可能有其他任何对象的其他成员?

Best是一个独立于编译器(甚至可移植)的解决方案。

更新:关于jalf提供的非常有用的答案:不,在此文件中我没有使用#pragma pack(x)。我在另一个结构中使用它,我使用的Bit字段在不使用#pragma pack(x)时填充。现在我只是因为我不知道Microsoft编译器如何解析std::string而陷入同样的​​陷阱而感到震惊。

1 个答案:

答案 0 :(得分:2)

与编译器无关且可移植的解决方案完全您向我们展示的代码。如果您不做任何事情来破坏它,编译器会正确地对齐所有内容。 (例如使用需要特殊对齐的SIMD类型,或使用#pragma pack

如果您使用的是#pragma pack,那么:

  1. 你为什么不告诉我们?
  2. 如果你向我们展示的代码在/ W4给你任何警告,那就怪微软了。代码是正确,可移植且安全的(与使用pack编译指示的代码不同)。

    微软对/ W4的警告提出了一些奇怪的想法。大多数编译器仅对看起来可能包含错误的内容发出警告。

    微软有一大堆警告基本上说“我没有理由怀疑这段代码有问题,但是如果你用不同的方式编写它可能包含一个bug”,这纯属无稽之谈。

    对于其他编译器,我通常建议在启用所有警告的情况下进行编译。在微软的编译器上,这不是真的可行。 (虽然你可以使用/ W4,并选择性地沉默特定的无意义警告)

    认为他们特别告诉你的是该结构包含填充字节(因此,如果你 使用#pragma pack,它会改变类的布局,其中一个受影响的类成员对此更改“敏感”。)

    如果可能,请考虑重新安排类成员,以便按大小的降序列出它们。这为您提供了更紧凑的类布局,仅在类的末尾添加了填充(如果有的话)。

    但是目前正在使用的类定义没有错误的