川合のプログラミング言語自作のためのテキスト第四版#001
(1) デバッグレベル
- acl4v2 には「デバッグレベル」という概念があります。
- このデバッグレベルは、コンパイラの最適化レベルのことだろうと誤解されることがあるのですが、それは違います。・・・紛らわしいのは「デバッグ時は最適化レベルを最低にしましょう」という正しいアドバイスがあって、それでデバッグと最適化レベルが結びついているせいだと思います。
- コンパイラの最適化は、生成する機械語の質を上げるためなら、プログラムに書かれた通りには処理しないで、あえて順序を変えたり共通化部分をまとめたりします(でも実行結果は変わりません)。こういうことをされると、変数〇〇に3が代入されるところからトレースしようとか思っても、デバッグがうまくいかないのです。コンパイラはその変数の更新タイミングを保持しなければいけないとは気づけないので、順序入れ替えなどをやってしまっているせいです。・・・だからデバッグ時は最適化をできるだけしないようにするわけです。・・・なお、printfでデバッグをする場合は、printf結果が変わってしまうと実行結果を変えたことになってしまうので、最適化レベルがmaxであっても支障はありません(最適化レベルが高いとコンパイルに時間がかかるという問題はありますが)。
- acl4v2 のデバッグレベルは最適化とは関係なくて、「このプログラムはまだバグがあるかもしれないから、とにかく用心深くチェックしながら実行してね」という意味です。つまりデバッグレベルが5のときでも、最適化レベルを最高にして構いませんし、デバッグレベルが0のときに最適化レベルを最低にしてもかまいません。速いか遅いかというよりも、バグチェックをしながら実行するかどうかの違いです(まあチェックをすれば基本的には少し遅くなりますが)。
- デバッグレベルによるチェック強化は、すべて実行時チェックによるものなので、コンパイル時に追加でエラーが見つかるということはありません(残念ながら)。
- デバッグレベルは a_DbgLv をdefineして指定します(ライブラリのincludeより前に)。デフォルトでは 2 になります。
- a_DbgLv=0 : リリース用のモードで、ライブラリ側でのエラーチェックは一切しなくなります。ただし、プログラムのバグではなく環境によっておこるエラー(メモリ確保の失敗、ファイルオープン時にファイルが見つからないなど)はチェックします。
- a_DbgLv=1 : エラーチェックはa_DbgLv=0と同等にまで省略されていますが、構造体の中にはエラーチェックのための情報を入れるスペースを確保します。これは「デバッグレベル2だと生じないのに、デバッグレベル0だと発生するバグ」なんて言う厄介な問題が出たときに、問題の切り分けを支援するために用意されているもので、普通はこのレベルを使うことはありません。
- a_DbgLv=2 : 処理速度があまり落ちないようなエラーチェックはすべてやります(デフォルト)。
- a_DbgLv=3 : レベル2とレベル5の間です。
- a_DbgLv=4 : レベル2とレベル5の間です。
- a_DbgLv=5 : どれだけ遅くなってもいいので、今実装されているエラーチェックは全部有効にします。
- acl4v2では、このデバッグレベルの考え方を重視しています。理由はこうです。・・・デバッグレベルがあるので、どれだけエラーチェックをしてもリリース時に実行速度の低下はありません。「こんなチェックをしたら確かに強力だけど、遅くて使い物にならない」みたいなチェックアルゴリズムがあった場合に、ためらうことなくエラーチェックのコードをいれることができます。必要なことはエラーチェックのための記述をためらうことではなく、どのデバッグレベル以上で有効になるのか正しく設定することだけです。
- 私自身は「まあこんなにチェックしても、自分がこのチェックで助かることはめったにないだろう」なんてうぬぼれていたのですが、チェックがあるとわかっているので「バグ探しはライブラリにやってもらえばいいやー」とばかりに適当に書くようになって、結果的にのびのびとプログラムを作れるようになりました。気分はいいです。おかげで新規にコードを書くときは1日に1回くらいはこのエラーチェック機能に助けられています。
こめんと欄