C言語の拡張機能と異なるコンパイラへの対応の難しさ
TL;DR: C言語コンパイラ開発者は、glibc や SDL などの標準ライブラリが GCC や clang などの特定のコンパイラを想定した非標準拡張に依存しているため、ポータビリティの実現が難しい課題に直面している。
C 言語のポータビリティはコンパイラの非標準拡張機能への依存によって複雑化している。多くの実務的な C コードは非標準的な動作と言語拡張にさまざまな程度で依存しており、<stdio.h> をプリプロセス・解析できなければ「hello world」さえ成功しない。
glibc と属性チェック
glibc の sys/cdefs.h に含まれる前処理指令は、特定のコンパイラを認識している。glibc による定義では「GCC, clang, and compatible compilers have various useful declarations that can be made with the '__attribute__' syntax. All of the ways we use this do fine if they are omitted for compilers that don't understand it.」と述べられており、GCC、clang、TinyC のみが __attribute__ サポート対象として認識される。GCC、clang、tcc 以外のコンパイラは同等の機能が提供されない。
さらに glibc の sys/epoll.h に含まれる struct epoll_event は __attribute__((packed)) を用いたパック構造体であり、GCC 組み込みヘッダーは /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.1/include/ に、clang 組み込みヘッダーは /usr/lib/clang/22/include/ に配置されている。glibc の limits.h は #include_next 拡張機能を使用し、GCC の組み込み limits.h に依存している一方、POSIX は limits.h が標準 C 定数に加えて POSIX 固有の定数を定義することを要求している。
複数の標準ライブラリ実装
異なるオペレーティングシステム上の標準ライブラリ実装も互換性の課題を生じさせる。OpenBSD は sys/cdefs.h で GCC バージョン向けに __only_inline マクロを __attribute__ と共に使用しており、_ANSI_LIBRARY マクロを尊重することで標準ヘッダー内での __only_inline 定義を省略できる。Android の bionic libc は _Nonnull と _Null_unspecified などの clang 固有拡張を備えている。一方、SDL_endian.h はバイトスワップ関数向けの機能検出ロジックを実装しており、clang は __GNUC__=4、__GNUC_MINOR__=2、__GNUC_PATCHLEVEL__=1 を定義して GCC 4.2.1 との互換性を主張している。
小規模なコンパイラの存在
より小規模で独立した C コンパイラには tcc、cproc、scc、vbcc、nwcc、kefir などが存在する。stddef.h、stdint.h、limits.h、float.h といった一部の C ヘッダーはコンパイラにより提供されている。
筆者の見立て
- C の標準化されていない非標準の動作に依存する設計は、すべての開発者が異なるコンパイラでコードをテストすることを求めるのは公平ではないと論じている。
- C のポータビリティはそれ自体が十分に困難であると述べている。
- 小規模コンパイラへの対応 (1) は敗北確定の取り組みであり、最新の GCC 拡張への対応を回避する (3) が最も簡単であり、多数のコードベースへの対応は GCC 互換性を主張することが現実的な方法であると解釈している。
- コードベースの多くが
#ifdef __GNUC__をチェックし、バージョン確認なしに新しい GCC 拡張を自由に使用することが (4) の問題である可能性を示唆している。 __has_builtin、__has_feature、__has_attributeといった機能テストマクロが、コンパイラ固有のガード代わりにより広く使用されるべきであると予想している。- 現在のところ、GCC と clang の準独占体制が *NIX 環境における現状であると解釈している。
この記事は元記事の事実のみに基づいて自動生成されました。
出典
元記事:「On C extensions, portability, and alternative compilers」 URL:https://lemon.rip/w/6-c-extensions-compilers/ 参照元:glibc、SDL、OpenBSD libc