让我们在一个名为TestHeader.h的头文件中考虑这个类。
class TestClass
{
public:
TestClass();
void DoStuff();
BOOL v1;
BOOL v2;
bool v11;
char u;
bool v6;
static TestClass* s_pAvatar;
static BOOL s_bInputHighlight;
int v7;
BOOL v3;
int v8;
char t;
bool v4;
bool v9[2];
};现在让我们考虑两个cpps,一个包含以下内容的main.cpp:
typedef bool BOOL;
#include "TestHeader.h"
int main()
{
TestClass C;
int s1 = sizeof( TestClass );
int s2 = sizeof( C.v1 );
void *v1p = &C.v1;
void *v2p = &C.v2;
int AddressDiff = ( int )v2p - ( int )v1p;
C.DoStuff( );
return 0;
}现在TestHeader.cpp包含:
typedef int BOOL;
#include "TestHeader.h"
TestClass* TestClass::s_pAvatar = 0;
void TestClass::DoStuff()
{
int S1 = sizeof(*this);
int S2 = sizeof(*s_pAvatar);
void *v1p = &v1;
void *v2p = &v2;
int AddressDiff = (int)v2p - (int)v1p;
int v1size = sizeof(v1);
if ( S1 != S2 )
{
}
}如果您在Visual 2013和Xcode 6.3.1上运行这个示例--这就是我测试的内容--您将看到,根据当前的cpp,TestClass的大小是不同的。在本例中,在main.cpp中,类应该是24个字节,而在TestHeader.cpp中,类是28字节,因为BOOL被不同的解释。
我的问题是,这是一个已知的C++问题吗?是否有任何链接标志来检查所有结构是否至少在所有编译单元中具有相同的大小?
发布于 2015-05-28 07:52:25
请注意,包含标题是将其文本包含在相关的翻译单元中。
因此,这两个不同的翻译单位得到了不同的类的定义。
类在各种翻译单位的定义,必须是相同的。因此,代码具有未定义的行为,违反了“一个定义规则”。
发布于 2015-05-28 08:12:44
这里真正的问题是,您正在定义一个不同类型的BOOL。这意味着您的编译器正在生成两种不同的结构,它们完全按照您的要求执行。
这是一个老笑话:病人:“医生,当我这么做的时候……”医生:“那就别那么做.”
在本例中,修复BOOL的定义,使其在所有情况下都是相同的(实现这一目标的最简单方法是只有一个定义,即在一个头文件中)。然而,要做到这一点,没有简单的诀窍。这是一个纪律,代码审查和理解什么实际得到定义的案例,如何和地点。
正如其他人指出的那样,这在技术上是未定义的行为,因为它违反了“您应该只有一个模块之间共享的东西的定义”的规则。
https://stackoverflow.com/questions/30500328
复制相似问题