次のオプションは,追加されたものです.
● -fbounds-check
このオプションは,GCCのFORTRAN言語のフロントエンドであるg77や,同じくJava言語のフロントエンドであるGCJで使用するオプションです.ここで詳しい説明はしません.このオプションを付加すると,加算,減算,乗算で発生する符号付きのオーバフローに対するトラップを生成します.もちろん処理速度は落ちますが,デバッグ中に使うと便利です.コンパイルと実行の結果を次に示します.
$ gcc test189.c -o test189
$ ./test189
20
0
-1524072448
$ gcc test189.c -o test189 -ftrapv
$ ./test189
20
0
アボートしました
$
このようにオーバフローして異常な値を検出したら,異常終了します.たいていの場合,オーバフローした値はメモリを破壊したりして,簡単には原因がわからないバグを生み出します.内部的に異常な数値を抱えたままプログラムが走ってしまうことを考えると,このオプションをデバッグ中につけておけば気持ちも晴れやか(?!)になるでしょう.ソースと生成されたコードをリスト1〜リスト3に示します.
このように加算,減算,乗算の命令が発生するごとにそれぞれ__addvsi3,__subvsi3,__mulvsi3を呼び出しています.
● -fnon-call-exceptions
throw例外をトラップすることを可能にするコードを生成します.これが,どこでも存在するとは限らないプラットホームに特有のランタイムサポートを要求することに注意してください.さらに,それは例外(つまりメモリ参照,浮動小数点命令)をトラップすることを単に可能にします.それは,SIGALRMのようなシグナルをトラップする処理とは関係ありません.C++特有の機能なので,ここでは触れません.このオプションをつけてもエラーにはなりませんが,単独では意味のないコードが付加されるだけです.ただしC++で書かれた例外処理とリンクしている場合は,このオプションを有効にする必要があります(リスト4).
● -funwind-tables
C++の例外処理を有効にします.詳しくは後で解説します.通常,例外処理を必要としないC言語では,デフォルトでこのオプションは無効となります.ただしC++で書かれた例外処理とリンクしている場合は,このオプションを有効にする必要があります.例外処理を記述していないソースのコンパイルにこのオプションをつけてもエラーにはなりませんが,単独では意味のないコードが付加されるだけです(リスト5).
● -fasynchronous-unwind-tables
もしターゲットマシンがサポートしているなら,warf2フォーマット形式のデバッグ情報ファイルを使います.デバッガやガベージコレクションで発生する非同期イベントによってスタックをアンワインドするために使用できます.
アンワインドとは,
main()
↓ func1()
↓ func2()
↓ func3()
のように関数func3を実行中にfunc1に戻る必要が出た場合,func2に戻らないためスタックを操作する必要ができます.それがアンワインドです.「スタックの巻き戻し」とも呼ばれています.C++ではこのような単純事例だけではありません.
● -fshort-wchar
Windowsとの互換上wchar_t をunsigned shortとして2バイトで定義するか,GCCでのデフォルトのとおりsigned long integerとして4バイトで定義するかを決定します.WINEを使う場合にはWindowsとの互換を取らないと動作しないと思います.ちなみにCygwinのgccではunsigned shortとして2バイトで定義されています.コンパイルと実行結果を次に示します.
$ gcc test192.c -o test192
$ gcc test192.c -fshort-wchar -o test192a
$ ./test192
4
$ ./test192a
2
$
ソースと生成されたコードをリスト6〜リスト8に示します.
● -fstack-limit-register=reg/-fstack-limit-symbol=sym/-fno-stack-limit
指定した値やシンボルのアドレスを越えてスタックが確保されないことを保証するためのコードを生成します.スタックが指定アドレスを超えて確保される場合,シグナルがレイズされます.ターゲットマシンの多くは,スタックが境界を越える前にシグナルがレイズされます.したがって,特別の警戒をとらずに,シグナルを認識することは可能です(リスト9).
$ gcc test193.c -fstack-limit-register=cx -S
上記のようにコンパイルした場合,生成されるコードはリスト10のようになります.
● -ftls-model=model
このオプションは,スレッド固有のデータを格納するための場所を割り当てる手段を指定するものです.-fpicオプションを指定しなければデフォルトは“initial-exec”,指定していれば“global-dynamic”がデフォルトです.後はlocal-dynamic,local-execが指定できます.tlsはThread Local Storageの略です.
● -finstrument-functions
このオプションは,関数の入口と出口にプロファイル用の呼び出しを生成します.関数の中に入った直後と関数から出る直前に,次の名称のプロファイル用の関数が呼び出されます.引き数は,対象の関数のアドレスとその呼び出し箇所です.プロトタイプは次のようになります.
void __cyg_profile_func_enter(
void *this_fn, void *call_site);
void __cyg_profile_func_exit(
void *this_fn, void *call_site);
ソースと生成されたコードをリスト11〜リスト13に示します.
オプションを付けると,__cyg_profile_func_enterと__cyg_profile_func_exitがそれぞれ関数の最初と最後に呼ばれていることがわかります.この関数を利用すれば,トレースを行うこともできます.
さて,変更されたオプションはたくさんあるので次回以降にまわします.表1に,コード生成規約に対するオプションをまとめます.次回は「コード生成規約に対するオプション」の補足,「最適化オプション」の補足を行う予定です.