2017-02-28 11 views
0

私は私のシステム構成と関係があると思われる奇妙なエラーが発生しています。私は、g ++を使って簡単なC++プログラムをコンパイル/リンクしています--version = g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609デフォルトの言語標準はC++ 98として文書化されていますが、-std = C++ 98オプションが指定されていても、出力.oファイルにはC++ 11のシンボルがあります。これは私のTEST.CPPです:ここではgccが明示的に指定されていても、C++ 11の標準を使用

#include <string> 
int main() { 
    std::string str = "Hello World!"; 
    return 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() 

__cxx11::*への参照に注目してください。私はそれらがコンパイラが挿入したC++ 11のシンボルだと推測します。私は成功したビルドを得ていますが、明らかにC++ 11を使用しています。ここではLDDから出力されます:

$ 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) 

私の実際のプロジェクトのためには、私はC++ 98をしているが、このために、コンパイラの問題のそうすることができませんサードパーティのLIBSにリンクしなければなりません。私のオブジェクトファイルは、それらのlibsのC++ 11シンボルを探していますが、見つけられません。どんな洞察?

+0

あなたのlibstdC++はC++ 11でコンパイルされているので、別のものを使用して非C++ 11のシンボルを取得する必要があるかもしれません。しかし、共有ライブラリにC++ 11と古いシンボルの両方が含まれているかどうかわからないので、確かに100%ではありません。 – awksp

+1

C++ 11とC++ 98は言語の*適合レベル*です。ライブラリをリンクして実行可能ファイルを生成するには、ライブラリが同じビルドシステムで開発されている必要があります。異なるコンパイラによって生成されたオブジェクトをリンクするべきではありません*あなたが宣言した言語適合レベル* –

+2

原則として、C++コードは、同じ正確なC++コンパイラでビルドされていない限り、「サードパーティライブラリ」にリンクすることはできません。もちろん、コンパイラは、このABI互換性が-std = C++ 98によって提供されているかどうかにかかわらず、同じコンパイラの他のバージョンとのABI互換性を提供することはできません。このオプションが行うことは、コードがコンパイルされる言語標準を指定することだけです。 –

答えて

2

hereのように、libstdC++ v.6は新旧のABIをサポートします。私はMakefileののG ++コマンドに

-D_GLIBCXX_USE_CXX11_ABI = 0

を配置しなければなりませんでした。これはlibの非互換性の面倒を見ました。

+0

コマンドラインやメイクファイルなどでマクロを定義することをお勧めします。ソースファイルでそれを定義することは、あなたのコードを使用しようとしている他の人にとっては壊れやすく、驚くべきことです。 – rubenvb

+0

Makefileのg ++​​コマンドに '-D_GLIBCXX_USE_CXX11_ABI = 0'を追加しました。それは間違いなくそれを行う方法です。ありがとう。 – Cosmo

関連する問題