gcc vs clang 公共库问题
gcc vs clang common library issue
我有两个应用程序,一个是用 gcc(c++) 编译的,另一个是用 clang++ 编译的。我将为这两个应用程序使用共同的共享提升库。我的问题是是否使用 clang 编译器或 gcc 编译器编译 boost 共享库。我可以在使用 clang 编译的应用程序中使用使用 gcc 编译的 boost 库吗?
简答:也许,也许不是。
长答案:
C++ 标准(或任何其他标准)不保证这种用法。
Clang 的开发人员确实付出了合理的努力来使 Clang 和 GCC 兼容,但出于最明显的原因(这是不同的编译器!)和一些不太明显的原因(对 C++ 规范含义的理解存在细微差别)例如),它们不是同一个编译器,因此可能在几个方面做不同的事情。
最明显的不兼容原因是:
- 类型定义的差异。
size_t
、int
和 long
之类的东西可能定义不同,因此使用 int func()
编译的函数在两者中可能 return 的大小值不同编译器。
- 名称修改的差异。例如,编译器如何区分
func(int)
和 func(long)
。
- 调用约定的差异。如何传递和 returned - 参数是在寄存器中还是在堆栈中,为寄存器参数的第一个到最后一个选择寄存器的顺序,等等。
- 异常处理的差异。编译器如何生成代码来解决在代码中特定位置抛出的异常,并返回到最近的
catch
语句。
这绝不是
的完整列表
上面的一些差异可能还取决于代码针对哪个目标编译 - 例如,它可能在 x86 上运行得很好,但针对 PowerPC 编译,并且在某些地方存在一些差异。
我相信没有人能够得出结论说 "yes, this will work" 或 "no it won't"。我确实经常使用 clang 和 gcc 的混合编译代码,而且它几乎一直都在工作。但这并不意味着它始终适用于所有情况。这才是真正的问题。
如果您有一个好的 test-suite [如果没有,您可能无论如何都应该修复它],您可以验证所有(测试的)代码是否按预期工作。这是比 "someone on some internet page wrote that it works" 更好的保证,因为它以您使用它的方式测试您正在使用的内容。
g++ 和 clang++ 作为编译器兼容(因为它们都遵循 Itanium ABI),但它们可能 带有不兼容的标准库实现。
g++ 带有一个名为 libstdc++ 的标准库实现。您可以指示 g++ 使用不同的实现,但这并非微不足道。
clang++ 有时没有自己的标准库实现(并配置为使用 g++ 提供的实现),有时带有一个名为 libc++ 的实现。可以通过一个命令行选项轻松地将 clang++ 切换为使用 libc++ 或 libstdc++。
所以你的问题归结为你的应用程序使用什么标准库实现。如果他们使用相同的实现,则需要使用该实现(以及任一编译器)构建 Boost。如果他们使用不同的实现,您需要两个单独的 Boost 构建。
在同一个应用程序中混合针对不同标准库实现构建的组件有时可以做到,但这并不简单,需要很多限制,并且像 boost 这样的东西要么不可行或完全不可能。
您需要为每个应用程序使用两个单独的 boost 构建,除非 boost 的使用仅限于一个动态库,然后由这些应用程序链接到该动态库,并且该动态库不会从其中包含 C++ std 库
我有两个应用程序,一个是用 gcc(c++) 编译的,另一个是用 clang++ 编译的。我将为这两个应用程序使用共同的共享提升库。我的问题是是否使用 clang 编译器或 gcc 编译器编译 boost 共享库。我可以在使用 clang 编译的应用程序中使用使用 gcc 编译的 boost 库吗?
简答:也许,也许不是。
长答案:
C++ 标准(或任何其他标准)不保证这种用法。
Clang 的开发人员确实付出了合理的努力来使 Clang 和 GCC 兼容,但出于最明显的原因(这是不同的编译器!)和一些不太明显的原因(对 C++ 规范含义的理解存在细微差别)例如),它们不是同一个编译器,因此可能在几个方面做不同的事情。
最明显的不兼容原因是:
- 类型定义的差异。
size_t
、int
和long
之类的东西可能定义不同,因此使用int func()
编译的函数在两者中可能 return 的大小值不同编译器。 - 名称修改的差异。例如,编译器如何区分
func(int)
和func(long)
。 - 调用约定的差异。如何传递和 returned - 参数是在寄存器中还是在堆栈中,为寄存器参数的第一个到最后一个选择寄存器的顺序,等等。
- 异常处理的差异。编译器如何生成代码来解决在代码中特定位置抛出的异常,并返回到最近的
catch
语句。
这绝不是
的完整列表上面的一些差异可能还取决于代码针对哪个目标编译 - 例如,它可能在 x86 上运行得很好,但针对 PowerPC 编译,并且在某些地方存在一些差异。
我相信没有人能够得出结论说 "yes, this will work" 或 "no it won't"。我确实经常使用 clang 和 gcc 的混合编译代码,而且它几乎一直都在工作。但这并不意味着它始终适用于所有情况。这才是真正的问题。
如果您有一个好的 test-suite [如果没有,您可能无论如何都应该修复它],您可以验证所有(测试的)代码是否按预期工作。这是比 "someone on some internet page wrote that it works" 更好的保证,因为它以您使用它的方式测试您正在使用的内容。
g++ 和 clang++ 作为编译器兼容(因为它们都遵循 Itanium ABI),但它们可能 带有不兼容的标准库实现。
g++ 带有一个名为 libstdc++ 的标准库实现。您可以指示 g++ 使用不同的实现,但这并非微不足道。
clang++ 有时没有自己的标准库实现(并配置为使用 g++ 提供的实现),有时带有一个名为 libc++ 的实现。可以通过一个命令行选项轻松地将 clang++ 切换为使用 libc++ 或 libstdc++。
所以你的问题归结为你的应用程序使用什么标准库实现。如果他们使用相同的实现,则需要使用该实现(以及任一编译器)构建 Boost。如果他们使用不同的实现,您需要两个单独的 Boost 构建。
在同一个应用程序中混合针对不同标准库实现构建的组件有时可以做到,但这并不简单,需要很多限制,并且像 boost 这样的东西要么不可行或完全不可能。
您需要为每个应用程序使用两个单独的 boost 构建,除非 boost 的使用仅限于一个动态库,然后由这些应用程序链接到该动态库,并且该动态库不会从其中包含 C++ std 库