[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.15 コード生成規約についてのオプション

以下は、機種独立のオプションで、コード生成において使われる インターフェース規約を制御する。

以下のほとんどのオプションには肯定形と否定形の両方の形式がある。 ‘-ffoo’ の否定形は ‘-fno-foo’ である。以下の表では、 どちらか一方の形しか列挙していない。デフォルトでないほうを列挙している。 もう一方の形式は、‘no-’ を取り除くか、追加すれば良い。

-fexceptions

例外処理を有効にする。例外を伝えるのに必要な余分のコードを生成する。 ターゲットによっては、この事は、すべての関数に対してフレームの 巻き上げを生成することを意味する。これによりデータサイズが著しく 大きくなるというオーバーヘッドが発生し得るが、実行には影響を与えない。 このオプションを指定しない場合、C++ のような、例外処理を普通必要とする 言語に対してはデフォルトで有効にし、C のような、普通必要としない言語に ついては無効にする。ただし、C++ で書かれた例外ハンドラと正しく 相互作用する必要のある C のコードをコンパイルするときは、このオプションを 有効にする必要がある。また、例外処理を使っていない、古い C++ プログラムを コンパイルするときには、このオプションを無効にして良い。

-fpcc-struct-return

「小さい」 structunion の値を、レジスタではなく、 大きなものの場合と同様にメモリに入れて返す。この規約は効率では 劣るが、GCC でコンパイルしたファイルと他のコンパイラでコンパイルした ファイルの間で相互に呼び出しが可能になるという利点がある。

構造体をメモリに入れて返す規約の詳細は、ターゲットのコンフィギュレーション マクロに依存する。

小さい構造体、共用体とは、その大きさとアラインメントが整数型の どれかに一致するものである。

-freg-struct-return

structunion の値を可能な場合にはレジスタで返す 規約を使う。この方法は、小さな構造体については ‘-fpcc-struct-return’ よりも効率が良い。

-fpcc-struct-return’ もその逆の ‘-freg-struct-return’ も 指定しない場合は、ターゲットで標準の規約がデフォルトとなる。 標準の規約がない場合は、GCC が標準のコンパイラであるターゲットを 除いて、‘-fpcc-struct-return’ をデフォルトとする。 GCC が標準のコンパイラである場合には、我々に標準の規約を選ぶ権利があるので、 効率の良い、レジスタで返すほうを選ぶ。

-fshort-enums

enum 型に対して、その型で宣言されている可能な範囲の値を 表すのに必要なバイト数しか割り当てない。もっと正確に言えば、 その場合の enum 型は、それを収めるのに充分で、かつ、最小の 整数型に同じである。

-fshort-double

double のサイズとして float と同じサイズを使う。

-fshared-data

データおよび非const 変数を、プライベートなデータとするのでなく、 共有データとすることを要求する。このことによる違いは、 共有データは同一のプログラムを実行する複数のプロセス間で共有されるが、 プライベートなデータは、プロセス毎にコピーを持つような、特定の OS の元でしか意味を持たない。

-fno-common

非初期化グローバル変数について、コモンブロックとして生成するのではなく、 オブジェクトファイルの bss セクションに割り当てる。 これにより、同じ変数が二つの異なるコンパイル単位で(extern なしで) 宣言されていると、リンク時にエラーとなる。これが唯一役に立つのは、 常にこのような動作をする他のシステムでのプログラムの動作を検証したい ときだろう。

-fno-ident

#ident’ 制御子を無視する。

-fno-gnu-linker

グローバルの初期化子(C++ のコンストラクタやデストラクタ等)を GNU リンカで使われている形式で出力しない(GNU リンカが初期化子を 取り扱う標準の方法となっているシステムの場合)。 GNU リンカでないリンカを使いたいときはこのオプションを指定する。 このとき、collect2 プログラムを使って、システムのリンカが コンストラクタとデストラクタを取り込むようにすることも必要となる。 (collect2 は GCC の配布物に含まれている。) collect2 を使わなければならないシステムに対しては、 コンパイラドライバである gcc は自動的にそうするように コンフィギュレーションされる。

-finhibit-size-directive

アセンブラ命令 .size や、あるいは関数が途中で分割され、 分割された二つの部分がメモリ中で離れた場所に置かれた場合に 問題となるようなものを出力しない。 このオプションは ‘crtstuff.c’ をコンパイルするときに使われる。 その他の場合には必要ないはずである。

-fverbose-asm

生成されたアセンブリコードに余分の注釈情報を加えて、読みやすくする。 このオプションは、一般に、生成されたアセンブリコードを実際に読む必要が ある人向けのものである(おそらく、本コンパイラ自体をデッバグするときに...)。

デフォルトの ‘-fno-verbose-asm’ は、余分の情報を出さず、 二つのアセンブラファイルを比較するときは便利である。

-fvolatile

ポインタを経由する全てのメモリ参照を揮発性と考える。

-fvolatile-global

外部データとグローバルデータに対する全てのメモリ参照を揮発性と 考える。GCC は、このオプションを指定しても、静的データ項目が揮発性である とは考えない。

-fvolatile-static

静的データに対する全てのメモリ参照を揮発性と考える。

-fpic

共有ライブラリで使うのに適した位置独立コード(PIC)を、ターゲットが サポートしていれば、生成する。 これで生成したコードは、全ての定数アドレスをグローバルオフセット表(GOT)を 通してアクセスする。動的ローダがプログラムの起動時に GOT のエントリを 解決する(動的ローダは GCC の一部ではない。オペレーティングシステムの 一部である)。リンクされた実行形式の GOT の大きさが、機種固有の最大値を 越えた場合は、‘-fpic’ が動作しないということを示すエラーメッセージを リンカが出す。その場合、代わりに ‘-fPIC’ を使って再コンパイル すること。(この最大値は、m88k では 16k、SPARC では 8k、m68k と RS/6000 では 32k である。386 にはこの制限はない。)

位置独立コードは特別なサポートを必要とし、そのために一定の機種でしか 動作しない。386 の場合は、GCC は System V については PIC を サポートしているが、Sun 386i についてはサポートしていない。 IBM RS/6000 向けに生成されたコードは常に位置独立である。

-fPIC

ターゲット機種でサポートされていれば、位置独立コードを出力する。 位置独立コードは動的リンクに適したもので、グローバルオフセット表の 大きさについての制限がない。このオプションは、m68k、m88k、SPARC で 違いが出る。

位置独立コードは特別なサポートを必要とし、そのために一定の機種でしか 動作しない。

-ffixed-reg

reg で指定されたレジスタを固定レジスタとして扱う。 生成されたコードは決してそのレジスタを参照してはならない (スタックポインタやフレームポインタやその他の決まった役割を持つものとして 参照する場合を除く)。

reg はレジスタの名前でなければならない。受け付けるレジスタ名は 機種依存であり、マシン記述マクロファイルの REGISTER_NAMES という マクロで定義される。

このオプションには否定形がない。三つの選択肢のうちの一つを 指定するからである。

-fcall-used-reg

reg で指定されたレジスタを関数呼び出しにより破壊される、 割当可能なレジスタとして扱う。このレジスタは、一時的な作業用や 関数呼び出しを越えて生存しない変数に割り当てられる可能性がある。 このオプションを付けてコンパイルされた関数は、レジスタ reg の セーブとリストアを行なわない。

このフラグをフレームポインタやスタックポインタに対して使うのは誤りである。 このフラグを、その他の、マシンの実行モデルにおいて固定した広く知られている 役割を持つレジスタに対して使うと、破壊的な結果をもたらす。

このオプションには否定形がない。三つの選択肢のうちの一つを指定するからである。

-fcall-saved-reg

reg という名前のレジスタを関数によりセーブされる割当可能な レジスタとして取り扱う。一時的なものや呼び出しを越えて生存する変数に 対しても割り当てられる。 こうしてコンパイルされた関数は、もし reg を使っていれば、それを セーブ/リストアする。

このフラグをフレームポインタやスタックポインタに対して使うのは誤りである。 このフラグを、その他の、マシンの実行モデルにおいて固定した広く知られている 役割を持つレジスタに対して使うと、破壊的な結果をもたらす。

このフラグを関数の戻り値を入れるレジスタに対して使うと、 別の種類の破壊的な結果になる。

このオプションには否定形がない。三つの選択肢のうちの一つを指定するからである。

-fpack-struct

構造体のメンバを全て穴の無いように詰め込む。 普通はこのオプションを使うことはないだろう。 コードの効率が落ちるし、構造体メンバのオフセットがシステムライブラリの ものと一致しなくなるからである。

-fcheck-memory-usage

各メモリ参照を検査するために余分なコードを生成する。GCC は、 ‘Checker’ のような、不正なメモリ参照を検知するプログラムに 適したコードを生成する。

普通は、この全てのコードをこのオプションを付けてコンパイルするか、 あるいは全く付けずにコンパイルする必要がある。

このオプションを付けてコンパイルしたコードと付けないでコンパイルした コードを混ぜる場合は、副作用があり、かつ、このオプションを付けて コンパイルしたコードから呼び出される全てのコードは、それ自身、 このオプションを付けてコンパイルされることを保証しなければならない。

ライブラリ関数のうち副作用のあるもの(例えば、read)を使うときは、 このオプションを指定してそのライブラリ関数を再コンパイルする訳には いかないこともあるだろう。その場合は、‘-fprefix-function-name’ オプションを指定して、読者のコードを包み込み、他の関数があたかも ‘-fcheck-memory-usage’ オプションつきでコンパイルされたかのように することを GCC に要求する。 これは、「スタブ」を呼び出すことによて行なわれる。スタブは検知器により 提供される。読者の呼び出しているあらゆる関数に対してスタブを 見つけたり、構築することが不可能な場合は、‘-fprefix-function-name’ オプションなしで ‘-fcheck-memory-usage’ を指定する必要がある。

このオプションを指定するときは、メモリ検査を有効にした関数内で asm__asm__ というキーワードを使うことはできない。 GCC は asm 文が行うことを理解できず、そのため適切なコードが 生成できないので、拒絶される。ただし、関数属性 no_check_memory_usage を付けると関数内のメモリ検査が無効になり、 asm 文をそういう関数内に置くことが可能になる。 検査された関数内で検査無しの関数をインライン展開するのは許されている。 インライン関数でのメモリアクセスは検査されないが、その結果検査される。

読者の asm 文を検査無しのインライン関数に移動するが、 それらがメモリをアクセスするなら、インライン関数内のサポートコードの 呼出しを追加して、任意の読み出し、書き出し、コピーが行われることを 指示することができる。これらの呼出しは、上で説明したスタブで行われるものに 似たものになるだろう。

-fprefix-function-name

関数名に対して生成されたシンボルにプレフィックスを付けることを GCC に 要求する。プレフィックスは関数の定義だけでなく関数呼び出し側にも 付けられる。このオプション付きでコンパイルしたコードとこのオプションなしで コンパイルしたコードはスタブを使わない限り、一緒にリンクすることは できない。

以下のコードを ‘-fprefix-function-name’ 付きでコンパイルすると

 
extern void bar (int);
void
foo (int a)
{
  return bar (a + 5);
}

GCC はコードが以下のように書かれているかのようにコンパイルする。

 
extern void prefix_bar (int);
void
prefix_foo (int a)
{
  return prefix_bar (a + 5);
}

このオプションは ‘-fcheck-memory-usage’ と合わせて使うように 設計されている。

-finstrument-functions

関数の入り口と出口に特別処理呼出しを生成する。 関数入り口点の直後と関数出口点の直前で、以下のプロファリング関数が 現在の関数とその呼出し側(call site)のアドレスを引数として 呼び出される。(いくつかのプラットフォームでは、 __builtin_return_address は現在の関数を越えては 動作しないので、呼出し側情報はそれ以外のプロファイリング関数からは 利用できない。)

 
void __cyg_profile_func_enter (void *this_fn, void *call_site);
void __cyg_profile_func_exit  (void *this_fn, void *call_site);

一番目の引数は、現在の関数の開始アドレスである。これは、シンボルテーブルから 正確に検索できるものである。

この特別処理は、他の関数内にインライン展開された関数に対しても 行われる。プロファイリング呼出しが、どこでインライン関数に 入り、どこで出たかを概念的に示す。これは、インライン関数に対し、 アドレスを取ることが可能な版が利用可能でなければならないことを 意味する。ある関数を使用しているところが全てインライン展開されるのなら、 これはコードサイズをさらに増やすことになる。読者の C コードで ‘extern inline’ を指定するなら、インライン関数のアドレス取得 可能版を提供しなければならない。(何はともあれ、これが普通の場合だが、 最適化により常に関数がインライン展開されるなら、運が良ければ、 static 版を提供しなくても済むかもしれない。)

関数に属性 no_instrument_function を指定すると、 この特別処理は行われない。これは例えば、上に示したプロファイリング関数や、 高優先度の割り込みルーチン、プロファイリング関数から安全に呼び出すことが できない関数(プロファイリングルーチンが出力をおこなったり、メモリを 確保するなら、おそらくシグナルハンドラが該当する)等に使われる。

-fstack-check

スタックの境界を越えないことを検証するコードを生成する。 マルチスレッドの環境ではこのフラグを指定すべきだろう。 シングルスレッドの環境では滅多に指定する必要がないだろう。 スタックが一個しかなければ、ほぼ全てのシステムでスタックのオーバーフローを 自動的に検出するからである。

-fargument-alias
-fargument-noalias
-fargument-noalias-global

仮引数間の依存関係および仮引数とグローバルデータの依存関係の可能性を 指定する。

-fargument-alias’ は、引数(仮引数)がお互いに別名になっている可能性が あること、それにグローバルデータの別名になっている可能性があることを 指定する。 ‘-fargument-noalias’ は引数はお互いに別名になっていることはないが、 グローバルデータの別名になっている可能性があることを指定する。 ‘-fargument-noaliase-global’ は、引数はお互いに別名になっていないし、 グローバルデータの別名にもなっていないことを指定する。

それぞれの言語は、その言語の規格で必要とされるオプションはなんであれ、 自動的に使うようになっている。そういうオプションを読者自身が 使う必要はないはずである。

-fleading-underscore

このオプションとその反対のオプションである ‘-fno-leading-underscore’ は、C のシンボルのオブジェクトファイル中での表現方法を強制的に 変更する。使い道の一つは、古いアセンブリコードとリンクするのを 助けることにある。

このオプションを指定するときは自分が何をしようとしているのかを 理解している必要があるということ、それに全てのターゲットがこのオプションを 完全にサポートしている訳ではないということに注意して欲しい。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html 1.78.