Next: , Previous: Generic Compiler Characteristics, Up: Compilers and Preprocessors


5.10.3 Cコンパイラの特徴

以下のマクロは,Cコンパイラを探し使用する方法を提供します.避けたほうが 良い構成物もいくつかありますが,それらは容易に回避可能なので,調査に使用 しているなら無くしてしまうこともないでしょう.

単一のバックスラッシュを含んでいる行を使用しないでください
それらは,HP-UX Cコンパイラにあるバグにはめられます(HP-UXの10.20,11.00, そして11iで調査しました).以下のソースをコンパイラで実行します.
          #ifdef __STDC__
          /\
          * A comment with backslash-newlines in it. %{ %} *\
          \
          /
          char str[] = "\\
          " A string with backslash-newlines in it %{ %} \\
          "";
          char apostrophe = '\\
          \
          '\
          ';
          #endif

以下のようになります.

          error-->cpp: "foo.c", line 13: error 4048: Non-terminating comment at end of file.
          error-->cpp: "foo.c", line 13: error 4033: Missing #endif at end of file.

単一のバックスラッシュを用いた行を削除することで,問題を解決できます.

出力が問題になる場合,一度に複数のファイルをコンパイルしないでください
HPのようにコンパイラには,ファイルが複数のとき,コンパイルしてい るファイル名を報告するものもあります.例えば以下のものです.
          $ cc a.c b.c
          a.c:
          b.c:

失敗を検出するために,コンパイラの出力を観察する場合,これは問題になるは ずです.‘cc -c a.c -o a.o; cc -c b.c -o b.o; cc a.o b.o -o c’で呼び 出すことで問題を解決します.

正しい#lineのサポートに依存しないで下さい
Solaris 8上で,c89(Sun WorkShop 6 update 2 C 5.3 Patch 111679-08 2002/05/09))は行番号全体で32767より大きな#line指示語を 拒絶します.さらにposixでは,これは有効になっていません.これは, Autoconfが#line指示語の生成を停止した理由です.
— Macro: AC_PROG_CC ([compiler-search-list])

使用するCコンパイラを決定します.CCが環境変数で設定されていない場 合,gccccを調査し,その後で他のCコンパイラを調査します. 出力変数CCを,見つかったコンパイラの名前に設定します.

しかし,このマクロはオプションで最初の引数を用いて呼び出すことも可能で, それが指定されている場合,それをスペースで区切られている検索するCコンパ イラのリストにする必要があります.これは,別のCコンパイラの検索リストを 指定する機会をユーザに与えます.例えば,デフォルトの順序が好きではない場 合,以下のようなAC_PROG_CCを呼び出すことが可能です.

          AC_PROG_CC(cl egcs gcc cc)

CコンパイラがデフォルトでANSI Cモードでない場合,そうするため のオプションを出力変数CCに追加します.このマクロは,様々なシステ ムでANSI Cを選択するように,様々なオプションを試します.関数の プロトタイプを正しく処理する場合,コンパイラがANSI Cモードだと 考えます.

このマクロを呼び出した後,CコンパイラがANSI Cを受け入れるよう に設定されているかどうかを調査することが可能です.そうでない場合,シェル 変数ac_cv_prog_cc_stdcは‘no’に設定されます.ソースコードを ANSI Cで書いている場合,Automake附属のプログラム ansi2knr を使用して,非ANSIfiedされたコピーを作成するこ とが可能です.AC_C_PROTOTYPES以下も参照してください.

GNU Cコンパイラを使用する場合,シェル変数のGCCを ‘yes’に設定します.出力変数CFLAGSがいまだ設定されていない場 合,GNU Cコンパイラに対しては-g -O2に設定し(GCCが ‘-g’を受け入れないシステムは‘-O2’),それ以外のコンパイラに対し ては-gに設定します.

— Macro: AC_PROG_CC_C_O

Cコンパイラが‘-c’と‘-o’オプションを同時に受け入れない場合, NO_MINUS_C_MINUS_Oを定義します.このマクロは,AC_PROG_CC で見つかったコンパイラと,パスの最初のccがそれと異なっている場合 はその両方を,実際にテストします.一つでも失敗した場合,テストは失敗しま す.このマクロは,GNU Makeがデフォルトのコンパイルルールを選択 するように作成されました.

— Macro: AC_PROG_CPP

出力変数CPPを,Cプリプロセッサを実行するコマンドに設定ます. ‘$CC -E’が動作しない場合,/lib/cppを使用します.拡張子が .cのファイルでCPPを実行することは移植性のためだけです.

プロセッサによっては,足りないインクルードファイルをエラーステータスで示 さないものもあります.そのようなプロセッサに対する内部変数は,プリプロセッ サからの標準エラーを調査するための他のマクロを設定し,警告が報告された場 合はテストに失敗したと判断します.それにもかかわらず,ほとんどのプリプロ セッサに対して,AC_PROG_CPP_WERRORも指定しない限り,警告でインク ルードファイルのテストは失敗します.

— Macro: AC_PROG_CPP_WERROR

これはAC_PROG_CPPのように動作しますが,プリプロセッサからの警告を, プリプロセッサが成功したことを示すステータスで終了した場合でも,エラーが あったとして処理します.これは,推奨されない注意のような,強制的な警告を 生成するヘッダを避けるときに役に立ちます.

以下のマクロは,Cコンパイラやマシンアーキテクチャの特徴を調査します.こ こでリストアップされない特徴を調査するために,AC_COMPILE_IFELSE (see Running the Compiler)やAC_RUN_IFELSE (see Run Time) を使用してください.

— Macro: AC_C_BACKSLASH_A

Cコンパイラが‘\a’を理解する場合,‘HAVE_C_BACKSLASH_A’を1に定義 します.

— Macro: AC_C_BIGENDIAN ([action-if-true], [action-if-false], [action-if-unknown])

(MotorolaとSPARCのCPUのように)wordが最上位バイトに最初に保存される場合, action-if-trueを実行します.(IntelとVAXのCPUのように)wordが最下位 バイトに最初に保存される場合,action-if-falseを実行します.

システムヘッダファイルからエンディアンを決定不可能な場合,このマクロはテ ストケースを実行します.クロスコンパイル時に,テストケースは実行されませ んが,いくつかのマジック変数を検索します.後者の状況でホストシステムのバ イト特性の決定に失敗した場合,action-if-unknownが実行されます.

action-if-trueのデフォルトは‘WORDS_BIGENDIAN’を定義することで す.action-if-falseのデフォルトは何もしないことです.そして最後に, action-if-unknownのデフォルトは,コンフィグレーションを中断し,イ ンストールしている人に,このテストをバイパスさせるために変数を前もって定 義するよう伝えます.

— Macro: AC_C_CONST

CコンパイラがANSI Cの修飾子constを完全にサポートしない 場合, constを空で定義します.__STDC__を定義しないCコンパ イラには,constをサポートするものもあります.__STDC__を定 義するCコンパイラには,constを完全にサポートしないものもあります. 全てのCコンパイラがconstをサポートするかのように,プログラムはそ れを使用することができます.サポートしないもののためにMakefileや コンフィグレーションヘッダファイルは,それを空で定義します.

Cコンパイラが無いために,インストールしている人がCコードをコンパイルする ためにC++コンパイラを使用することもあります.CとC++はconstを異な る方法で処理するので,これはconstの問題が生じます.例えば,以下の ようにします.

          const int foo;

Cでは有効ですがC++ではそうではありません.残念ながら,これらの違いを constを空で定義することで誤魔化すことは不可能です.

autoconfがこの状況を検出した場合,一般的に実際問題としてより良 い結果になるので,それはconstのままにしておきます.しかし,C コー ドコンパイルするためにC++コンパイラを使用することは推奨されていませんし, サポートもしていません.そして,この状況で問題が生じたインストール者は, CコードをコンパイルするためにGCCのようなCコンパイラを入手すべきです.

— Macro: AC_C_RESTRICT

Cコンパイラがrestrictキーワードを認識する場合は何もしません. (__restrict__restrict__,または_Restrict)という, かわったつづりだけを認識する場合,restrictをそれに定義します.そ れ以外では,restrictを空で定義します.このため,プログラムでは restrictをすべてのCコンパイラがサポートしているかのように,単純に 使用してかまいません.そうしない人は,Makefileやコンフィグレーショ ンヘッダで頑張って定義して下さい.

C++でのrestrictキーワードサポートは要求されていませんが,いくつか のC++コンパイラはそのキーワードを受け入れます.このマクロは,そこでも動 作します.

— Macro: AC_C_VOLATILE

Cコンパイラがキーワードvolatileを理解しない場合,volatile を空で定義します.プログラムではvolatileをサポートしているコンパ イラのように単純に使用することが可能です.サポートしないものに対しては, Makefileやコンフィグレーションヘッダで,それを空として定義されま す.

プログラムの正当性がvolatileの意味に依存している場合,単純に空で 定義するとある意味ではコードが壊れます.しかし,volatileをサポー トしていないコンパイラでは,自分で何とかしてください.少なくともプログラ ムはコンパイルされますが,多分駄目でしょう.

一般的に,volatileキーワードはANSI Cの機能なので, __STDC__が定義されているときだけ,volatileが利用可能だと期 待するかもしれません.しかし,Ultrix 4.3のネイティブコンパイラは volatileをサポートとしていますが,__STDC__を定義しません.

— Macro: AC_C_INLINE

Cコンパイラがキーワードinlineをサポートする場合,何もしません.そ れ以外では,受け入れられるものによって,inline__inline____inlineに定義し,それ以外ではinline を空で定義します.

— Macro: AC_C_CHAR_UNSIGNED

Cの型charがunsignedの場合,Cコンパイラが前もって定義していない限 り,__CHAR_UNSIGNED__を定義します.

— Macro: AC_C_LONG_DOUBLE

Cコンパイラが,doubleの型以上の範囲で動作するlong double の型をサポートしている場合,HAVE_LONG_DOUBLEを定義します.

— Macro: AC_C_STRINGIZE

Cプリプロセッサが文字列作成オペレータをサポートする場合, HAVE_STRINGIZEを定義します.文字列作成オペレータは‘#’と,以 下のようなマクロで見つかります.

          #define x(y) #y
— Macro: AC_C_PROTOTYPES

関数のプロトタイプをコンパイラが理解する場合(AC_PROG_CCで決定され ます),‘PROTOTYPES’と__PROTOTYPESを定義します.コンパイラが プロトタイプを処理しない場合,関数定義のプロトタイプを止めるために, Automake配布物でインストールされるansi2knrを使用すべきです.関数 のプロトタイプに対して,最初にPARAMSを定義すべきです.

          #ifndef PARAMS
          # if PROTOTYPES
          #  define PARAMS(protos) protos
          # else /* no PROTOTYPES */
          #  define PARAMS(protos) ()
          # endif /* no PROTOTYPES */
          #endif

そして,以下のように使用してください.

          size_t my_strlen PARAMS ((const char *));

このマクロは,__PROTOTYPESも定義します.これは,ユーザの名前空間 を侵害するマクロが使用不可能なヘッダファイルの利便性ためです.

— Macro: AC_PROG_GCC_TRADITIONAL

使用しているGNU Cコンパイラとioctlが, ‘-traditional’無しでは正確に動作しない場合,出力変数CCに ‘-traditional’を加えます.それは通常,修正されたヘッダファイルが古 いシステムにインストールされていないときに発生します.GNU Cコ ンパイラの最近のバージョンは,インストール時に,自動的にヘッダファイルを 修正するので,これはほとんど問題になりません.