C++ 不同C/C+的ABI兼容性+;语言版本+;GNU扩展

C++ 不同C/C+的ABI兼容性+;语言版本+;GNU扩展,c++,c,gcc,linker,C++,C,Gcc,Linker,我目前正在使用GCC4.8.2,没有std选项来编译我的c/c++代码。 现在我想使用一些新的C/C++特性,这些特性是由较新的C/C++语言版本提供的 (Un?)幸运的是,gcc理解C/C++的多种风格: c90,c99,c11,gnu90,gnu99,gnu11 c++98,c++03,c++11,gnu++98,gnu++03,gnu++11 目前我在问自己: 对于每个c/c++版本,我需要一个单独的库,还是可以将一个库用于多个c/c++版本? 当我使用gnu扩展对应的c/c++版

我目前正在使用GCC4.8.2,没有std选项来编译我的c/c++代码。 现在我想使用一些新的C/C++特性,这些特性是由较新的C/C++语言版本提供的

(Un?)幸运的是,gcc理解C/C++的多种风格:

  • c90,c99,c11,gnu90,gnu99,gnu11
  • c++98,c++03,c++11,gnu++98,gnu++03,gnu++11

目前我在问自己:

  • 对于每个c/c++版本,我需要一个单独的库,还是可以将一个库用于多个c/c++版本?
  • 当我使用gnu扩展对应的c/c++版本时,我尤其可以链接使用特定c/c++版本编译的库吗?

澄清(基于评论)

请注意,我只使用了一个编译器。并非只有修订号不同的两个gcc。 当只使用一个gcc编译器时,我只要求不同std选项之间存在ABI不兼容。

一般来说:

  • 不能在同一个程序中组合不同的语言版本,这将导致在许多库标题中违反“一个定义规则”
在有限的情况下,您可能会发现一些类实际上不会随着语言版本的变化而变化。然而,这种情况很少见,C++11标准要求使用右值引用,在C++03模式下根本不可用

对于支持和不支持GNU扩展的版本,您可能会获得更多的成功,但是您仍然需要通过预处理器运行每个头,并验证编译器使用这两个选项看到的令牌序列是否完全相同

这与ABI更改完全不同,这可能会导致不同编译器变体之间的内存布局或名称损坏有所不同


通过避免使用任何版本和语言特定的功能,您还可以避免在自己的公共API上违反单定义规则。本质上,这意味着一个扁平的C API。

语言本身的风格不应该改变ABI,只是编译器本身的不同版本。您可能不想将新的编译器与在4.6之前使用编译器编译的库结合在一起,但gcc的现代版本彼此兼容(至少在x86上是如此)。[C++标准模板库中的大多数都是在头文件中实现的——因为它是“模板”,所以编译时只要编译器和标题兼容的任何版本的语言都是好的,ABI就已经改变了很多。从GCC4.8.1rev1到4.8.1rev5,我必须重新编译我的整个静态库,以便它链接。否则它会给我未定义的符号等等。。从4.7.2到4.8.1更糟。如果是动态库(.dll或.so),则链接在运行时完成,工作正常。唯一担心的是CRT版本,很少会出现崩溃/问题。对于静态库(.a或.lib或.o),这是一场噩梦。@MatstPetersson-这可能是对C ABI的合理假设,但理论上,
-std
选项可能会调用不同的链接器选项。我不依赖于C++发布库之间的小版本兼容性。