填充空类的多重推导。 只有在Windows下(Padding with multiple der

2019-10-18 08:58发布

今天,我们在我的代码是产生疯狂的房价出现了问题。 我终于煮下来的事实,我的消息类是错误的大小,即使我打包在一个字节,并有单元测试,以确保这不会不会发生。 (原来的单元测试在Windows下不运行,但这是另外一个问题。)

我有一个traits类模板,它是除了一些空洞的static const S和enum S和A的实现noncopyable类里面是空的。

当我从上述两种的派生类,所得到的类是由1个字节填充,但是只有在Windows下,并且当我来自两类派生。 如果我从一个或另一个派生的类不填充出来。

我知道我在这里与特定平台的领土#pragma ,但它似乎有些奇怪,我认为只有在多个公共继承这难道不是做什么,我期待它做的事。

现在的问题是:为什么在空类的多个公共继承的情况下确实MSVC垫出来的类由1个字节?

下面是issustrates问题的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)

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

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

编辑:显示的偏移mBuf WRT使用类的开头:

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

揭示了:

Offset: 1
文章来源: Padding with multiple derivation of empty classes. Only under Windows