使用多个派生的空类填充。仅在Windows下

时间:2013-07-12 16:53:13

标签: c++ visual-studio-2010 visual-studio-2008 gcc

今天我们遇到了一个问题,我的代码产生了疯狂的价格。我最终把它归结为我的消息类大小错误的事实,即使我在一个字节上打包并进行单元测试以确保不会发生这种情况。 (事实证明单元测试不是在Windows下运行,但这是另一个问题。)

我有一个traits类模板,除了一些static constenum之外是空的,并且noncopyable类的实现是空的。

当我从上述两个类派生一个类时,生成的类被填充1个字节,但仅在下在Windows下,如果我从两个派生类。如果我从一个或另一个派生出来,那么这个课程就不会被填补。

我意识到我在#pragma处于特定于平台的区域,但对我而言似乎很奇怪,只有在多次公共继承期间,这不会达到我期望它做的那样。

问题是:为什么MSVC在多次公共继承空类的情况下将类填充1个字节?

这是一个解决问题的SSCCE:

#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;

#pragma pack (1)

template <size_t ExpectedSize>
class Traits
{
public:
    static const size_t mExpSize = ExpectedSize;
};

class noncopyable
{
public:
    noncopyable() {};
    ~noncopyable() {};
private:
    noncopyable& operator= (const noncopyable&);
    noncopyable (const noncopyable&);
};

class NotEmpty1
{
public:
    char mBuf [33];
};

class NotEmpty2
:
    public Traits <33>

{
public:
    char mBuf [33];
};

class NotEmpty3
:
    public noncopyable
{
public:
    char mBuf [33];
};

class NotEmpty4
:
    public Traits <33>,
    public noncopyable
{
public:
    char mBuf[33];
};

int main()
{
    cout << "Case 1: " << sizeof (NotEmpty1) << "\n"
        << "Case 2: " << sizeof (NotEmpty2) << "\n"
        << "Case 3: " << sizeof (NotEmpty3) << "\n"
        << "Case 4: " << sizeof (NotEmpty4) << "\n"
        ;
}

这里的想法是所有NotEmpty完全 33个字节。在linux下(使用G ++ 4.4.6.4),它们是:

Case 1: 33
Case 2: 33
Case 3: 33
Case 4: 33

在Windows下(使用MSVC 9和10),它们不是:

Case 1: 33
Case 2: 33
Case 3: 33
Case 4: 34

修改:当我使用时:

#pragma pack (show)

在各种地方,编译器总是说:

1>main.cpp(57): warning C4810: value of pragma pack(show) == 1

修改:使用以下内容显示班级开头的mBuf偏移量:

cout << "Offset: " << offsetof(NotEmpty4, mBuf) << "\n";

揭示:

Offset: 1

0 个答案:

没有答案