编译此头文件:
// 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/