Clang と GCC の相違点

Clang コンパイラのオプションは GCC とほぼ共通なので、異なる部分のみを解説します。Clang コンパイラはオプションによって、コンパイラドライバ、コンパイラ、アセンブラの役割を果たすという構造になっているので、単一の exe になっています。(C の場合は clang.exe、C++ の場合は clang++.exe となります。)また、SOLID ツールチェーンの設定では、リンク時には gcc.exe あるいは g++.exe を呼び出してリンクを行います。

  • 文字コード GCC は -finput-charset/-fexec-charset で cp932(Shift_JIS) 等を指定し、ソースコードやアセンブラ出力の文字コードをデフォルトの UTF-8 から変更できますが、Clang は常に UTF-8 のみとなります。

  • pragma, attribute

    pragma や attribute は基本的にそれぞれのコンパイラに固有のものとなります。できるだけ使用しないようにしてください。特に #pragma GCC ... の形式のプラグマは GCC のみ、 #pragma clang ... の形式のプラグマは Clang のみとなります。

    • よく使われる例

      • GCC で、最適化オフの範囲指定 #pragma GCC optimize("O0") は、 Clang では #pragma clang optimize off となります。

        Clang(6.0.0 時点)は __attribute__((optimize("O3")))#pragma clang optimize ("-O3") のような、関数単位や範囲指定の最適化指定はできません。 ( #pragma clang optimize XXX では、最適化の onoff の指定のみ可能です。 on を指定した場合でも、最適化オプションが指定されていない場合は、最適化は行われません。)

  • gstabs, gstabs+

    stabs, stabs+ 形式のデバッグ情報は未サポートです。

  • mthumb-interwork

    このオプションは Clang には存在しないので、Clang にパッチを当て、無視するようにしています。Clang では常に ARM/Thumb interworking が有効なコードが生成されます。

  • marm

    Clang にこのオプションを渡すと、内部で -mno-thumb と解釈されます。SOLID ツールチェーンの Clang は GCC をリンカとして使用しているため、この(GCC が未サポートの)-mno-thumb オプションが GCC に渡されてしまうとリンクエラーになるため、Clang にパッチを当て、無視するようにしています。(s002 以降)

  • specs= file

    Clang には specs ファイルが存在しないので無視されます。

  • arm-*-eabi ターゲット時の enum サイズの仕様

    GCC は arm-*-eabi ターゲット時は aapcs ABI となり、enum が取り得る値の範囲に応じた可変長バイトとなりますが、Clang は固定長(4 もしくは 8 バイト)です。これは Linux(arm-*-gnueabi* ターゲット)の aapcs-linux ABI と同等の設定になっています。SOLID ではわかりやすさや互換性等を考慮し、Clang の方に合わせた設定となっています。(s002 以降)