今天,我们在我的代码是产生疯狂的房价出现了问题。 我终于煮下来的事实,我的消息类是错误的大小,即使我打包在一个字节,并有单元测试,以确保这不会不会发生。 (原来的单元测试在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