Cpp-Debug笔记——在库和main中使用相同的类名引发的惨案
背景
程序A 动态链接 库B,库B中有一个内部使用的Timers
类,程序A中也有一个内部使用的Timers
,两者都没有被置于namespace中。
现象
Release编译时一切正常,Debug编译时库B中的Timers
类的构造函数没有被执行。
调试
在调用Timers
的构造函数的地方尝试按F11
跳转到库B中的Timers
的构造函数中时,却跳转到了程序A内部使用的Timers
中。
分析
库B在编译时,看不到程序A中的Timers
,因此调用库B中的Timers
却实际调用程序A中的Timers
的原因肯定是链接的时候发生了符号覆盖。也就是说,库B中的Timers
和程序A中的Timers
中的构造器的signature一样的话,它们对应的符号也是一样的,而由于程序A和库B是动态链接的,因此链接的时候不会提示符号冲突,而是直接使用了程序A中的符号,这就导致了库B中的代码想调用库B中的Timers
的构造函数,却意外调用了程序A中具有相同符号的Timers
的构造函数。这也解释了为什么release编译时没有问题,因为此时Timers
的构造器和其他method都被内联了,没有符号。
解决方案
把库B中的所有代码都包在一个B自己的namespace里。这样B里的所有符号都是以这个全局唯一的namespace为前缀的,就不会跟其他库或者程序里的符号重名了。