编译此标题:
// 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
而陷入同样的陷阱而感到震惊。
答案 0 :(得分:2)
与编译器无关且可移植的解决方案完全您向我们展示的代码。如果您不做任何事情来破坏它,编译器会正确地对齐所有内容。 (例如使用需要特殊对齐的SIMD类型,或使用#pragma pack
)
如果您使用的是#pragma pack
,那么:
如果你向我们展示的代码在/ W4给你任何警告,那就怪微软了。代码是正确,可移植且安全的(与使用pack
编译指示的代码不同)。
微软对/ W4的警告提出了一些奇怪的想法。大多数编译器仅对看起来可能包含错误的内容发出警告。
微软有一大堆警告基本上说“我没有理由怀疑这段代码有问题,但是如果你用不同的方式编写它可能包含一个bug”,这纯属无稽之谈。
对于其他编译器,我通常建议在启用所有警告的情况下进行编译。在微软的编译器上,这不是真的可行。 (虽然你可以使用/ W4,并选择性地沉默特定的无意义警告)
他认为他们特别告诉你的是该结构包含填充字节(因此,如果你 使用#pragma pack
,它会改变类的布局,其中一个受影响的类成员对此更改“敏感”。)
如果可能,请考虑重新安排类成员,以便按大小的降序列出它们。这为您提供了更紧凑的类布局,仅在类的末尾添加了填充(如果有的话)。
但是目前正在使用的类定义没有错误的。