7

GCC はデフォルトで 4 バイトwchar_tを使用します。で-fshort-wchar2 バイトを取得するオプションを設定できます。しかし、コンパイラ オプションをソース ファイルに設定すると、有名な警告メッセージが表示されます。wchar_tL"string constants"

foo.o は 2 バイトwchar_tを使用しますが、出力は 4 バイトを使用しますwchar_twchar_tオブジェクト間での値の使用は失敗する可能性があります

私は本当に 2 バイトが必要なwchar_tので、出力にもこのバリアントを使用したいと考えています。私が欲しいものを伝えるリンカーオプションはありますか?

編集

この警告は、リンカが有効な出力を生成することを妨げません。しかし、何十もの誤った警告が他のメッセージを覆い隠しています。

4

2 に答える 2

16

binutils では、このエラー メッセージは次の場所にありますbfd/elf32-arm.c

「警告: %B は %u-byte wchar_t を使用しますが、出力は %u-byte wchar_t を使用します。オブジェクト間での wchar_t 値の使用は失敗する可能性があります」

ただし、binutils をさらに調べると、出力の wchar_t サイズがどこにも 4 に初期化されていないことがわかります。では、「出力 wchar_t サイズ」を決定するものは何ですか? 実際には、最初に指定されたオブジェクトldが出力属性を初期化します。次のオブジェクトは、それらの属性をそれにマージします。gcc/g++ とリンクするとld内部で実行されるので、実行gcc -v方法ldを試してみてください。これにより、実行可能ファイルに暗黙的にリンクされている内部オブジェクト ファイル (独自のものに加えて) についての洞察が得られます。

たとえば、gcc (eg gcc -v -shared -o libfoobar.so foo.o bar.o) とリンクすると、次の呼び出しが発生します。

ld ... crtbegin_so.o foo.o bar.o crtend_so.o ...

つまり、次のオブジェクトが実際に (順番に) リンクされています。

  • crtbegin_so.o (暗黙的に)
  • foo.o
  • bar.o
  • crtend_so.o (暗黙的に)

ld の機能は次のとおりです。

  1. 出力属性セットは空から始まります。
  2. crtbegin_so.o属性のマージ。出力属性に含まれるようになりましたout_attr[Tag_ABI_PCS_wchar_t] == 4
  3. foo.o属性のマージ。foo.o が でビルドされている場合-fshort-wcharin_attr[Tag_ABI_PCS_wchar_t] == 2これにより競合が発生し、表示されている警告が表示されます。

ld コマンドラインで crtbegin_so.o と foo.o を交換すると、代わりに次の警告が表示されます。

ld: 警告: android-ndk-r9d/platforms/android-16/arch-arm/usr/lib/crtbegin_so.o は 4 バイトの wchar_t を使用しますが、出力は 2 バイトの wchar_t を使用します。オブジェクト全体で wchar_t 値を使用すると失敗する場合がある

ご覧のとおり、これは入力と出力の非互換性の問題ではなく、リンクされた 2 つのオブジェクト ファイル間の (認識された) 非互換性の問題です。

私たちはそれについて何ができますか?

  • 2008 の時点で、この警告を抑制するフラグがldサポートされています。--no-wchar-size-warningしかし、あなたが言ったように、警告を無差別に抑制することには欠点があります。

  • -fshort-wchar を使用してツールチェーンを再構築できます。

  • Tag_ABI_PCS_wchar_tそれらが非依存的であると本当に信じている場合は、内部 gcc オブジェクト バイナリからタグを取り除くことができますsizeof(wchar_t)。これは、ツールチェーンを再構築するよりも簡単かもしれません。そのために、私がかつて書いたこのユーティリティを使用できます。(libgcc.a を解凍し、そのオブジェクト ファイルを変更して再パックする必要がある場合があります。)

于 2014-05-27T18:49:49.790 に答える
1

これは警告であり、エラーではありません。これは無視できますが、4-byte でコンパイルされた他のライブラリとリンクすると問題が発生しますwchar_t。2バイトwchar_tを使用する必要がある場合は、それらのライブラリの代替を見つけるか、再コンパイルする必要があります

あなたも試すことができます-fwide-exec-charset=UTF-16

  • -fwide-exec-charset=charset
    • ワイド文字列と文字定数に使用されるワイド実行文字セットを設定します。デフォルトは、UTF-32 または UTF-16 の幅に対応する方ですwchar_t。と同様に-fexec-charset、charset は、システムの iconv ライブラリ ルーチンでサポートされている任意のエンコーディングにすることができます。ただし、 に正確に適合しないエンコーディングでは問題が発生しますwchar_t

C11 をサポートしている場合は、必要に応じて (文字列リテラルのプレフィックスを付けて) 使用しchar16_tu変換することができます。wchar_t

于 2013-10-21T08:30:31.380 に答える