在我们公司,直到最近,我们还没有使用命名空间,因为一些编译器不能很好地支持它们。
这导致以下错误的多次发生:
文件_A.cpp
class Node {
Data *ptr;
Node() { ptr = new Data; }
~Node() { delete ptr; }
};
file_B.cpp
class Node {
vector<int> v;
Point *pt;
Node(int x,int y) { pt = new Point(x,y); v.push_back(0); }
~Node() { delete pt; }
};
void foo() {
Node n(10,10);
...
} // calls file_B::~Node() !!!
每个作者
Node
都不知道另一个 Node
的存在,但由于他预计这个类名可能会被重用,所以他没有用它创建一个 .hpp 文件。编译器默默地删除其中一个析构函数,因为它们的签名匹配,并且很难找到该错误,因为它可能不会在不同的计算机中复制。
一旦发现错误,人们逐渐意识到它,并尝试将定义密封在未命名的命名空间中,或者避免内联类主体中的成员函数[见下文]。
无意中我的意思是,
Node
类没有在 .hpp 文件中定义,并且至少有一个类成员在类定义之间不匹配...... 方式 1:包含在未命名的命名空间中
namespace {
class Node {
Data *ptr;
Node() { ptr = new Data; }
~Node() { delete ptr; }
};
}
方式二:避免内联
class Node {
Data *ptr;
Node();
~Node();
};
Node::Node() { ptr = new Data; }
Node::~Node() { delete ptr; }
最佳答案
如果您的代码库足够大,可以证明努力是合理的,您可以 自定义现有编译器 来解决您的问题:
在这两种情况下,都需要几天或几周的时间,最困难的是部分理解编译器内部表示(GCC 的 Gimple & Tree)和组织(例如 pass)。
我是 MELT 的主要作者,我很乐意帮助您解决 MELT,所以请随时与我联系。
关于c++ - 检测意外的弱链接符号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8318146/