4

编译这个头文件:

// 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 sMyStringMicrosoft的官方帮助建议使用 a #pragma pack(x),其中x1、2、4 取决于在其结构/类中使用的成员。

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

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

更新:关于 jalf 提供的非常有用的答案:不,在这个文件中我没有使用#pragma pack(x). 我在另一个结构中使用了它,在该结构中我使用了在不使用#pragma pack(x). 现在我只是惊恐地陷入了同样的陷阱,因为我不知道 Microsoft 编译器是如何解析的std::string

4

1 回答 1

4

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

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

  1. 你为什么不给我们看?
  2. 不要

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

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

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

对于其他编译器,我通常建议在编译时启用所有警告。在微软的编译器上,这并不可行。(尽管您可以使用 /W4,并选择性地使特定的无意义警告静音)

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

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

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

于 2013-06-27T09:18:23.887 回答