ARM Compiler ツールチェーン(5 以前)との相違点
ここでは GCC/Clang と ARM Compiler ツールチェーン (以後 armcc) との、実際に問い合わせがあった相違点を解説します。armcc 向けのコードを移植する際等に参考にしてください。
(GCC と Clang はコンパイラオプションやプラグマ等独自拡張にある程度互換性がありますが、armcc は基本的に互換性が無いので、本項は網羅的な移植ガイドではありません。FAQ や Tips に近いものです。)
armcc には様々なバージョンが存在しますが、ここでは問い合わせが多かった、バージョン 4 と 5 について扱います。(バージョンが明記されていない場合、4 と 5 の全バージョンで共通の仕様となります。)
注釈
armcc のバージョン 6 以降は Clang ベースの armclang になったので、コンパイラ部分は GCC/Clang との互換性が改善されています。その一例として、後述する wchar_t
のデフォルトサイズが同じになった点があります。その一方で、もともと GCC に合わせた仕様だったものが Clang 寄りに変化している場合もあります。例えば、デフォルトの enum の仕様が armcc は GCC と同じ -fshort-enums
(可変長)だったのが、armclang は Clang と同じ -fno-short-enums
(固定長)となっています。
ワイド文字のサイズ
armcc では wchar_t
や L"..."
のデフォルトサイズは 16-bit となります。
これは --wchar16
オプションを指定したのと同じ設定となります。
GCC/Clang は 32-bit で、armcc の --wchar32
オプション指定と同等です。
これは ABI の違いとなりますので、異なるバイナリをリンクしようとした場合
uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
のような警告が出ます。GCC (GNU ld) の場合、 --no-wchar-size-warning
オプションでこの警告を抑制することが可能ですが、正常動作は期待できません。(LLVM lld にはこのオプションは存在しません。)
注釈
armclang の wchar_t
のデフォルトサイズは 32-bit です。
armcc のリンカ armlink の $$Sub$$
や $$Super$$
による既存関数のオーバーライド
GCC/Clang (GNU ld/LLVM lld) では --wrap=SYMBOL
オプションで同等の機能が実現可能です。
__attribute__((at( ADDRESS )))
で変数を絶対アドレス ADDRESS に配置
GCC/Clang (GNU ld/LLVM lld) では、直接はサポートされませんが、リンカスクリプトで以下のように指定することで、同等の機能が実現可能です。
unsigned char __attribute__((section (".my_buf_abs_section"))) my_buf[128];
.my_buf_abs_section ADDRESS : {
KEEP(*(.my_buf_abs_section))
}
armcc のイメージ変換ツール fromelf の scatter-loading 機能の様な複数バイナリの生成
GCC/Clang (GNU ld/LLVM lld) は未サポートです。
armcc の付属ライブラリの _mutex_XXX のようなマルチスレッドアプリケーションにおけるロックをユーザー実装できる機能
s003 から正式サポートされました。SOLID-OS を使用する場合、SOLID-OS がロックを実装しているので、ユーザーは何もしなくても付属ライブラリをマルチスレッドアプリケーションで安全に使用可能です。
詳細は マルチコンテキスト対応(exeGCC) を参照してください。
注釈
正確には s002 にも NetBSD libc 由来のマルチスレッド対応用のフックは存在していましたが、非公開の内部機能でした。s003 ではそれをより使いやすい形に修正するとともに、pthread API 実装を用意することで C11/C++11 などのマルチスレッド機能にも対応可能にしました。