这是示例:
Main.cpp
:
#include "MooFoobar.h"
#include "MooTestFoobar.h"
#include "FoobarUser.h"
namespace moo::test::xxx {
struct X
{
void* operator new(const size_t size);
FoobarUser m_User;
};
void* X::operator new(const size_t size)
{
printf("Allocated size: %zd\n", size);
return malloc(size);
}
} // namespace moo::test::xxx
int main()
{
new moo::test::xxx::X;
printf("Actual size: %zd, member size: %zd\n", sizeof(moo::test::xxx::X), sizeof(moo::test::xxx::FoobarUser));
return 0;
}
MooFoobar.h
:
namespace moo {
struct Foobar
{
char m_Foo[64];
};
} // namespace moo
MooTestFoobar.h
:
namespace moo::test {
struct Foobar
{
char m_Foo[32];
};
} // namespace moo::test
FoobarUser.h
:
#include "MooFoobar.h"
namespace moo::test::xxx {
struct FoobarUser
{
FoobarUser();
~FoobarUser();
Foobar m_Foobar;
};
} // namespace moo::test::xxx
FoobarUser.cpp
:
#include "FoobarUser.h"
#include <cstdio>
moo::test::xxx::FoobarUser::FoobarUser()
: m_Foobar()
{
printf("FoobarUser constructor, size: %zd\n", sizeof(*this));
}
moo::test::xxx::FoobarUser::~FoobarUser()
{}
所以这里发生了什么:根据包含的顺序,不合格的名称被解析为不同的类型,FoobarUser.cpp
我们得到 size 64
,Main.cpp
我们得到 size 32
。不仅sizeof
不同 -operator new
以不正确的 ( 32
) 大小调用,而且构造函数将初始化 的大小64
,这会导致内存损坏。
在 clang 和 msvc 中,这个程序的结果是:
Allocated size: 32
FoobarUser constructor, size: 64
Actual size: 32, member size: 32
这听起来很可疑,基本上意味着如果存在名称冲突,则不合格的名称是不可行的,因为根据包含顺序,它可能会导致本质上是不正确的程序。
但是我在 C++ std 中找不到任何可以说明任何无效/格式错误的代码的点。谁能帮我?
它真的是标准而不是一些复杂的大规模编译器问题(尽管我真的看不出编译器如何解决这种情况)?