VCのリリースビルドとデバッグビルドの違い
伊藤兎さんから昨日の日記(http://d.hatena.ne.jp/torazuka/20110816/cpp)にコメント頂いたのをきっかけに、リリースビルドとデバッグビルドを自分が理解していないことに気づいたので、調べました。そのメモです。
そもそも、「PDB(プログラムデータベース)ファイルを生成するのがデバッグビルドである」という誤解をしていました。
ということを知りました。
リリースビルドとデバッグビルドの操作上の違い
上の記事のとおり、[ソリューション構成]ドロップダウンリストの値を「Release」に変更してからビルドするのが、リリースビルドです。
[ソリューション構成]は、初期値で「Debug」がアクティブになっています。
開発は、基本的に「Debug」のまま行います。十分にデバッグをした後、リリース版の実行ファイルを取得したいときに、明示的にリリースビルドを実行します。…という認識です。
リリースビルドとデバッグビルドの実質上の違い
コードの最適化が行われるのが、リリースビルドです。
しかし、その結果、デバッグビルドでは起こらないエラーが発生する可能性があります。
- リリース ビルド作成時によくある問題 http://msdn.microsoft.com/ja-jp/library/dykf6bx9.aspx
上のページでは、リリースビルドとデバッグビルドでメモリアロケータが異なるために起きる問題や、VERIFYの代わりに重要な検証をASSERTに書いてしまっていた(その結果、リリースビルドでASSERTが評価されなかった)ことによる問題などが、解説されています。
デバッグビルドでは、メモリの上書きを検知するための機構が使われます。リリースビルドには、この機構がありません。特にこの違いが原因で、プログラムの挙動が異なるケースが多いそうです。
ただ、リリースビルド時とデバッグビルド時のコンパイラ動作の差異については、まだ資料を見つけていません。その1つが、伊藤さんが書いてくださった「初期化していない変数の自動初期化」だと思うのですが。
もう少し調べるか、デバッグビルドで生成されるアセンブリを比較すれば、確認できるかもしれません。
# ヲイ確認しろよって椅子蹴られそうですが、ちょっと本の裁断で忙しいので、今日のところは保留で…。
おまけ
その他、派生して覚えたことのメモです。
(その2)デバッグ情報の形式
デバッグ情報の形式には、次の3つがあります。
- C7互換
- プログラムデータベース
- エディットコンティニュのプログラムデータベース(※初期値)
これらは、[プロジェクト]→[プロパティ]→[構成プロパティ]→[C/C++]→[全般]の[デバッグ情報の形式]で確認・変更できます。
ちなみに、エディットコンティニュとは、このことですね。
エディット・コンティニューは(中略)、デバッギング セッションの途中でソース コードを変更し、デバッグ対象のアプリケーションにコードの変更を適用することができます。この際には、デバッギングを停止し、リビルドを行い、デバッガを再起動し、アプリケーションをバグが発生した状態にまで進めるといった操作は必要ありません。
Microsoft Visual C++ 6.0 の エディット・コンティニューによるデバッギングの強化
- /Z7、/Zi、/ZI (デバッグ情報の形式) http://msdn.microsoft.com/ja-jp/library/958x11bc(v=VS.100).aspx
上のページによると、「ほとんどの最適化処理はエディット コンティニュと互換性がない」そうです。
リリースビルドではプログラムデータベース、デバッグビルドではエディットコンティニュのプログラムデータベースが、デバッグ情報の形式の初期値になっているのは、そのためでしょうか。