gpt4 book ai didi

C++ 类合并,链接器问题

转载 作者:搜寻专家 更新时间:2023-10-31 01:01:35 26 4
gpt4 key购买 nike

让我们考虑一下我今天通过浏览一个相当大的代码库发现的以下情况(为了示例而举例说明了真实源代码):

其中一个团队创建了以下两个文件和一组接口(interface)(MoreBaseBase)。到目前为止一切都很好。

* file1.h *

class MoreBase
{
public:
MoreBase();
virtual ~MoreBase();
};

class Base : public MoreBase
{
public:
virtual ~Base();
virtual void func() const = 0;
};

class A : public Base
{
public:
A();
~A();
virtual void func() const;
};

* file1.cpp *

#include <iostream>
#include "file1.h"

using namespace std;

MoreBase::MoreBase() { cout << "file 1 MoreBase::MoreBase " << (void*)this << endl; }
MoreBase::~MoreBase() { cout << "file 1 ~MoreBase::MoreBase " << (void*)this << endl;}

Base::~Base() { cout << "file 1 ~Base::Base " << (void*)this << endl; }

A::~A() { cout << "file1 ~A::A() "<< (void*)this << endl; }

A::A() { cout << "file 1 A::A() "<< (void*)this << endl; }

void A::func() const { cout << "file 1 A::func() "<< (void*)this << endl; }

但是还有另一个团队,在完全不同的部门、建筑、国家、大陆,正在开发完全不同的东西......例如:

* file2.h *

int some2method();

* file2.cpp *

#include <iostream>

using namespace std;

class Base
{
public:
virtual ~Base();
virtual void something() const = 0;
};

class B : public Base
{
public:
B();
~B();
virtual void something() const;
};

B::~B() { cout << "file 2 B::~B() "<< (void*)this << endl; }

B::B() { cout << "file 2 B::B() "<< (void*)this << endl; }

void B::something() const { cout << "file 2 B::something() "<< (void*)this << endl; }

// VARIABLE
const Base& x = B(); // ***

int some2method()
{
x.something();
return 42;
}

* main.cpp *

#include "file2.h"

int main()
{
some2method();
}

让我们像这样编译它:

$ g++ -ggdb main.cpp file1.cpp file2.cpp -o test

让我们运行:

 $ ./test
file 1 MoreBase::MoreBase 0x6022f0
file 2 B::B() 0x6022f0
file 2 B::something() 0x6022f0
file 2 B::~B() 0x6022f0
file 1 ~Base::Base 0x6022f0
file 1 ~MoreBase::MoreBase 0x6022f0

你不觉得它构造了一个我从未请求过的 MoreBase 对象很奇怪吗?

不幸的是 (1) 公司开发一种产品,因此所有源文件都链接到一个可执行文件中。

不幸的是 (2) Base 是我们工作领域中非常常见的名称...

幸运的是 (1) 在 some2method() 中找到了标记为 //*** 的行,应用程序崩溃了 < strong>用 GCC 编译时。这就是我开始调查的地方(现在它在外面,所以甚至没有崩溃)。

显然问题是:这到底怎么可能?为什么链接器合并了两个完全不相关的类,尽管它们不幸共享相同的名称。这是未定义的行为、已定义的东西还是仅仅是不幸?

编辑:我不要求解决问题(它可以用命名空间修复,或者简单地重命名非公共(public)基类),我只是想要知道根本原因:)

最佳答案

如评论中所述,这打破了包含 UB 的单一定义规则。防止这种情况的方法是使用命名空间,特别是将任何私有(private)类定义(在 cpp 文件中读取)放在匿名命名空间中。

编辑:抱歉,我刚刚意识到,WhozCraig 已经在评论中提供了完全相同的答案

关于C++ 类合并,链接器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28897171/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com