编译此头文件:

// 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,具体取决于在struct /类中使用的成员。

不,我不知道为std::string使用哪种对齐方式?我的想法是std::string也不是编译器,也不是平台无关的。有什么方法可以解决该问题,尤其是考虑到其他可能有其他资格的成员吗?

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

更新:关于jalf提供的非常有用的答案:不,在此文件中,我没有使用#pragma pack(x)。我在另一个结构中使用了它,在这里我使用的位域在不使用#pragma pack(x)时会被填充。现在,我刚被警告要遇到相同的陷阱,因为我不知道Microsoft编译器如何解析std::string

最佳答案

独立于编译器的可移植解决方案就是您显示给我们的代码。如果您不做任何事情来破坏它,则编译器将负责正确对齐所有内容。 (例如,使用需要特殊对齐的SIMD类型,或使用#pragma pack)

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

  • 您为什么不告诉我们?
  • 不要。

  • 如果您显示给我们的代码在/ W4处给您任何警告,请怪Microsoft。该代码是正确,可移植且安全的(不同于使用pack编译指示的代码)。

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

    微软有很多警告,基本上说:“我没有理由怀疑此代码有问题,但是如果您用不同的方式编写它,则可能包含错误”,这完全是胡说八道。

    对于其他编译器,我通常建议在启用所有警告的情况下进行编译。在Microsoft的编译器上,这实际上并不可行。 (尽管您可以使用/ W4,并选择性地使特定的废话警告静音)

    我认为他们特别告诉您的是该结构包含填充字节(因此,如果您确实使用#pragma pack,它将更改类的布局,并且受影响的类成员之一将对此更改“敏感” )。

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

    但是您当前使用的类定义没有任何问题。

    关于c++ - 确保std::string正确对齐,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17339169/

    10-13 04:58