本次rapidjson相关gdb core是否因违反ODR(单一定义规则)导致?
问题1解答
你的判断完全正确,本次崩溃确实是违反了C++的**单定义规则(ODR)**导致的:
- 你的业务代码和依赖的动态库各自引入了独立的rapidjson代码,且都使用了默认的
rapidjson根命名空间,编译后会生成完全同名的全局符号。 - 程序启动加载动态库时,动态链接器会对全局可见的同名字符做统一决议,默认所有同名符号都会绑定到最先被加载的那一份定义上。如果两份rapidjson的版本不一致,或者编译配置存在差异,就会出现内存布局、内部执行逻辑不匹配的问题。本次崩溃就是动态库原本要调用自己内置的rapidjson逻辑,实际执行了你新引入的不兼容的rapidjson代码,最终触发断言异常。你通过自定义命名空间隔离两份rapidjson的符号,刚好解决了ODR冲突的问题。
问题2解答
编译阶段不报previous declaration错误的原因和你的判断一致:
- 编译阶段只会处理单个编译单元的语法校验、声明匹配校验,你的业务代码编译时只能看到你引入的rapidjson头文件声明,完全感知不到动态库中存在的同名rapidjson符号。
- 动态库的符号冲突属于运行时链接阶段的问题:默认编译动态库时内部的符号默认是全局可见的,和静态库在链接阶段就会做全量符号检查、重复定义直接报错不同,动态库的符号决议是在程序启动/运行时执行的,所以编译期不会抛出冲突错误。
内容的提问来源于stack exchange,提问作者Jon Phil
相关产品推荐
相关产品推荐

