2009-11-05 56 views
2

我在想,编译A类的一个编译器不允许多重继承,并且编译一个支持它的类B(而B类是从A类派生的),会产生什么后果。C++分类编译器(vtables)?

我真的不明白链接过程...可以一起使用两者吗?在这种情况下使用不同的编译器有什么不利之处?使用B类的代码能够正常工作吗?

谢谢。

+0

它可以概括为:每个编译器制造商都可以定义自己的ABI。由于ABI的不同使得一个编译器的代码不能被另一个编译器使用,所以这个过程不可用。事实上,使用相同编译器和不同标志编译的代码会导致相同的问题(调试和发布二进制文件与某些编译器不兼容)。所以从技术上讲,所有编译单元都应该使用相同的标志编译相同的编译器(否则你会遇到麻烦)。 – 2009-11-05 17:40:11

回答

10

作为一般规则,不要有史以来用不同的编译器编译C++程序的一部分。

不同的编译器可能会使用不同的编译模式来处理符号重组阶段,因此很难单独编译的内容之间的链接工作。

看到有关重整name_mangling

+0

另外,vtable实现,异常处理等(整个C++ ABI)可能会有所不同。 – sellibitze 2009-11-05 13:36:19

+0

感谢您的提醒。我绝不会这样做。 – ash 2009-11-05 13:43:13

+0

如果您使用共享对象/ DLL,则可以这样做。然后有一个通用的链接约定,以便不同的编译器可以一起工作。如果你在外部供应商的应用程序中使用DLL,你不知道他们使用了什么编译器。 您将不得不将应用程序分解为“组件”共享对象/ DLL。 – 2009-11-05 13:59:49

3

对象布局(虚表指针的位置,虚函数表格式,子对象的位置,等)的文档不保证是编译器之间相同。

2

这不仅仅是不能相互交谈的课程。在头文件中声明但仅由其中一个编译器编译的裸函数由于名称变形而对其他编译器不可见。

另外,由编译器编译的不编译main()的任何静态类/成员将不会正确初始化,因为编译器的运行时不会被执行。即使像64位长算术(在32位平台上),由于冲突的运行时库可能无法正确链接。

2

作为附录上述Arkaitz的职位,你可能会发现其他问题,可以停止码从不同的编译器内置的编译单元一起工作:

  1. 数据大小的问题(例如,一个编译器将使用32个整数,该其他64位)
  2. 数据对准问题
  3. 问题与堆内存

基本上任何地方的C++/C标准不是非常特定的事为编译器之间的差异留有余地,因此可以混合使用它们的问题范围