C++ 使用c++;11标准,即使98明确规定

C++ 使用c++;11标准,即使98明确规定,c++,c++11,gcc,c++98,C++,C++11,Gcc,C++98,我发现一个奇怪的错误,我怀疑它与我的系统配置有关。我用g++来编译/连接一个简单的C++程序——版本=代码> g++(ubuntu5.4.06Ubuntu1~16.04.4)5.4.0 20160609 < /Cord>。默认的语言标准被记录为c++98,但是即使指定了-std=c++98选项,我也在output.o文件中看到了c++11符号。这是我的测试。cpp: #include <string> int main() { std::string str = "Hello W

我发现一个奇怪的错误,我怀疑它与我的系统配置有关。我用g++来编译/连接一个简单的C++程序——版本=代码> g++(ubuntu5.4.06Ubuntu1~16.04.4)5.4.0 20160609 < /Cord>。默认的语言标准被记录为c++98,但是即使指定了-std=c++98选项,我也在output.o文件中看到了c++11符号。这是我的测试。cpp:

#include <string>
int main() {
  std::string str = "Hello World!";
  return 0;
}
对于我的实际项目,我必须链接到第三方libs,它们是c++98,但由于这个编译器问题,我无法这样做。我的对象文件正在这些库中查找c++11符号,但找不到它们。有什么见解吗?

如前所述,libstdc++v.6支持新的和旧的ABI。我必须把它放在一个地方

-D_GLIBCXX_使用_CXX11_ABI=0


到Makefile的g++命令。这解决了lib的不兼容性问题

在我看来,您的libstdc++是用c++11编译的,因此您可能需要使用另一个来获取非c++11符号。但不是100%确定,因为我不确定共享库是否可以同时包含c++11和更旧的SYMBOLS,c++11和c++98是该语言的一致性级别。要链接库以生成可执行文件,必须使用相同的构建系统开发该库。你不应该把不同编译器所生成的对象链接在一起,不管你声明的语言一致性级别。作为经验法则,C++代码不能链接到“第三方库”,除非它是用同一个完全的C++编译器构建的。当然,编译器可以提供与同一编译器的其他版本的ABI兼容性,但不清楚-std=c++98是否提供了这种ABI兼容性。此选项所做的只是指定编译代码所依据的语言标准。在v5时代的某个地方,GCC更改了ABI版本,使其具有一个小字符串优化
std::string
,而不是C++11不兼容的写时复制字符串实现。我认为,即使是对于C++03/98,这也是可以的,因为它们仍然是一致的。我怀疑您可以通过强制它或您的标准库使用旧的ABI来修复您的问题。由于字符串只是一个模板,如果幸运的话,它可能在不重新编译标准库的情况下工作。名称_cxx11有误导性,它也可能是_version_7,但由于它是与C++11同时引入的。。。这并不意味着编译器使用的是C++11,它只是一个ABI细节。您应该更喜欢在命令行或makefile或其他任何地方定义该宏。在源文件中定义它是有限的、脆弱的,对于其他试图使用您的代码的人来说是非常令人惊讶的。我在Makefile的g++命令中添加了
-D\u GLIBCXX\u use\u cx11\u ABI=0
。这绝对是做这件事的方法。谢谢
$ g++ -c -Wall -std=c++98 -o test.o test.cpp
$ g++ -Wall -std=c++98 -o test test.o
$ nm -C test.o
                 U __gxx_personality_v0
0000000000000000 T main
                 U __stack_chk_fail
                 U _Unwind_Resume
                 U std::allocator<char>::allocator()
                 U std::allocator<char>::~allocator()
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
                 U std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
$ ldd test
    linux-vdso.so.1 =>  (0x00007ffc381f5000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6548d48000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6548b32000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6548768000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f654845f000)
    /lib64/ld-linux-x86-64.so.2 (0x000055785493c000)