编译器构造-如何在C++中解决这些名称冲突
compiler construction - How these names conflict is resolved in C++?
假设我有这样的物理结构:
/
+-- conflicttest
| +-- A.cpp
| +-- A.h
| +-- main.cpp
+-- libconflict
| +-- conflict
| | +-- A.h
| | +-- B.h
| +-- A.cpp
| +-- B.cpp
这些都是诽谤的来源,深吸一口气:
libconflict:中的class B
标头
// libconflict B.h
class B
{
public:
void bar();
protected:
int j_;
};
libconflict:中的class B
实现
// libconflict B.cpp
#include "conflict/B.h"
void B::bar()
{
std::cout << "B::bar" << std::endl;
}
libconflict:中的class A
标头
// libconflict A.h
# include "conflict/B.h"
class A : public B
{
public:
A();
private:
int i_;
};
libconflict:中的class A
实现
#include "conflict/A.h"
A::A()
{
std::cout << "libconflict A is alive" << std::endl;
i_ = 51; // some random fields and values... I should admit I am lost
j_ = 47;
}
现在,冲突测试的来源,它几乎结束了:
冲突测试中的class A
标头:
// conflicttest A.h
class A
{
public:
A();
void foo();
};
冲突测试中的class A
实现:
// conflicttest A.cpp
#include "A.h"
A::A()
{
std::cout << "A is alive" << std::endl;
}
void A::foo()
{
std::cout << "A::foo" << std::endl;
}
最后,main.cpp
:
// main.cpp in conflicttest
#include "conflict/A.h"
int main()
{
B* b = new A;
b->bar();
return 0;
}
Phew。。。我正在使用Visual Studio 2010构建此解决方案。CCD_ 8是针对静态库CCD_。这编译起来很有魅力,但信不信由你,输出是:
A is alive
B::bar
链接器实际上使用来自conflicttest
的符号A
,它绝对不是B
,更糟的是,它可以调用B::bar()
。
我迷路了,为什么编译器不抱怨?
您违反了一个定义规则。
编译器没有抱怨,因为它在跨越翻译单元边界时可以检测到的东西有限。
我猜您实际上并没有链接您的conflictlib。但实际上,就是不要那样做。如果绝对必须,请使用名称空间。
答案很简单。你们对编译器撒谎了,作为回报,编译器正在把你们的谎言还给你们。函数的内部实现是这样的,即它们只是在每个类的某个函数表中排列。当你有不同的类声明时,编译器会根据它来推导函数表,但推导是错误的。该表中没有函数名,因此编译器无法检测到故障情况。
您对类A有两种不同的定义。这违反了ODR。因此,该程序不是一个有效的C++程序。编译器不需要诊断此错误。
相关文章:
- 如何解决GTest和LibTorch联动冲突
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- 如何解决两个不使用命名空间的第三方库之间的类名冲突?
- 如何解决此C++访问冲突问题
- GNUMakefile 和 gcc:解决冲突"-std=c++"需求的顺序
- 如何解决头文件中的变量冲突?
- Eigen SparseLU解决错误读取访问冲突,这>m_sup_to_col被0x111011101110112
- LR解析器如何解决歧义和冲突
- 如何解决GMP的32位和64位库之间的冲突
- C++将冲突解决映射为javaHashMap
- C++STL如何unordered_map解决冲突?
- 如何解决"sprintf"的冲突类型?
- 尝试解决链接器警告:默认库'MSVCRT'与使用其他库冲突
- 解决LNK4098:默认库'MSVCRT'冲突 (DCMTK) 和 LNK2038/LNK2005
- 包括文件冲突解决方案
- 用于分组以解决冲突的算法
- 如何解决调用 dll 方法时的访问冲突写入位置
- 如何解决编译器枚举重新声明冲突
- 解决运行时库冲突的好方法是什么?
- 在C++中使用多个静态库解决冲突