のラベルは消え、関数名の色が灰色から黒に変わります。これが起こるたびに、エディット・コンティニューは次のメッセージを表示してユーザーに通知を行います。

図 8.
[OK] を選択すると、実行ポイントは CountAway() の閉じ中括弧の位置に置かれます。これは、この関数から返る直前であることを示しているので、正しい位置です。きわめて稀なケースですが、実行ポイントが間違った位置に置かれることがあります。この場合には、正しい行で右クリックを行い、コンテキスト メニューの [次に実行するステートメント] を選択する必要があります。
エディット・コンティニューの動作
エディット・コンティニューは、/ZI コンパイラ スイッチが使用されている場合に、ビルドの時点から始まります。このスイッチは、コンパイラ ドライバであるCL.EXEによって解析されます。ドライバはこのスイッチを次のように複数のスイッチに展開して、コンパイラ フロント エンド (C1XX.DLL) とコンパイラ バック エンド (C2.DLL) に渡します。
| スイッチ
| CL.EXEのアクション
| スイッチの機能
| /GF
| C1XX.DLL に渡す
| 重複する文字列を削除する。
| /FD
| C1XX.DLL に渡す
| ファイルの依存関係を生成する。
| /Zi
| C1XX.DLL に渡す
| プログラム データベース ファイル (.pdb) の中にデバッグ情報を生成する。
| /Gy
| C2.DLL に渡す
| 関数レベルのリンクを有効にする。
| /Zi
| C2.DLL に渡す
| プログラム データベース ファイル (.pdb) の中にデバッグ情報を生成する。
| /ZI
| C2.DLL に渡す
| コンパイラ バック エンドに、エディット・コンティニューが有効になっていることを知らせる。
| | | | | | |
また、コンパイラはコンパイルされた個々のソース ファイルについて生成されたオブジェクト モジュール (.obj) に、次の情報を格納します。
| 環境変数
| 値
| ENC_CWD
| ビルド時のコンパイラのワーキング ディレクトリ。
| ENC_CL
| CL.EXE (コンパイラ ドライバ) へのパス。
| ENC_SRC
| コンパイルされるソース ファイルへのパス。
| ENC_PDB
| プログラム データベース ファイル (.pdb) へのパス。
| ENC_CMD
| ファイルのコンパイルに使用されたコマンド ラインの内容。
| -editandcontinue
| リンカに対して、オブジェクト モジュール (.obj) がエディット・コンティニューに対応してコンパイルされていることを通知する。
| | | | | | |
デバッギング セッションにおいて、IDE の中でファイルが編集されると、デバッガはエディット・コンティニューが有効になっているかどうか、またファイルがエディット・コンティニューに対応しているかどうかを調べます。もしそうであれば、[デバッグ] メニューとツールバーの [コードに対する変更を適用] コマンドが有効となります。
[コードに対する変更を適用] コマンドが呼び出されると、変更されたファイルとそれに依存するファイルが、.obj モジュールに格納されている環境変数情報を使って再コンパイルされます (上の表を参照)。再コンパイルされる各ファイルについて、古い.obj モジュールが.encの拡張子に変更され、新しい .obj モジュールが生成されます。コンパイル エラーが起こった場合には、エラーが報告され、コードの変更はデバッグ対象のアプリケーションに対して適用されません。コンパイルエラーが起こらなかった場合は、新しい .obj モジュールのバイナリ コードがメモリに追加され、アプリケーションの元のコードの代わりに使用されます。
エディット・コンティニューの制限
Visual C++ 6.0 IDE の外でのエディット・コンティニューの使用
Visual C++ プロジェクト 構築システムは、コードの変更が起こった後に、どのファイルを再コンパイルする必要があるかどうかを判断しなくてはなりません。また、エディット・コンティニューのコンポーネント (mspdb60.dll、msobj10.dll、msenc10.dll) は Visual C++ IDE の中でしか利用できません。外部のソース エディタをエディット・コンティニューと連係させるためには、ファイルが IDE の中でデバッグされているプロジェクトの一部になっている必要があります。ユーザーは、外部エディタで変更したファイルを保存し、フォーカスを IDE に戻さなくてはなりません。変更されたファイルを再ロードするように求めるプロンプトが表示されるので、これに [はい] と答えた後に、コードに対する変更を適用してください。
リソース ファイルの変更
リンカはリンク時に、実行可能ファイルにバイナリのリソース データを追加します。エディット・コンティニュー操作の際には、実行可能ファイルの再リンクは行われないので、オリジナルのリソース データが使用され、このデータに対する変更を実行時に適用することはできません。
読み取り専用ファイルの変更
変更されたファイルをエディット・コンティニューが再コンパイルするためには、いったんファイルが保存される必要がありますが、読み取り専用属性があるとファイルを保存することはできません。また、この保護機能は、ファイルがソース管理環境からチェックアウトされないまま上書きされるのを防ぐ役割を果たしています。
最適化を使ってコンパイルされたソース コードの変更
コンパイラ最適化が有効になっていると、コンパイラはソース コードを分析し、プログラマが意図したとおりの処理を実行する、より小さく高速なコードにコンパイルします。結果として得られるバイナリ コードは、最適化なしで生成されるものとは一般に大きく異なっており、ソース コードの個々の行には対応していません。ソース コードと最適化されたバイナリ コードの間の違いのために、エディット・コンティニューは正しい実行ポイントを決定したり、ブレークポイントを再バインドしたり、コードの変更を適用したりすることができなくなります。
/ZI コンパイラ スイッチによってエディット・コンティニューが有効になっており、それと同時にコンパイラ最適化スイッチも有効になっていると、次のようなコンパイラ エラーが発生します。コマンド ラインのエラー D2016 : コマンド ライン オプション '/ZI' と '/Ox' は同時に指定できません
例外処理ブロックの変更
変更されたファイルが例外処理サポート付きでコンパイルされていた場合 (/GX コンパイラ スイッチ)、実行ポイントよりも前のコードの変更は、例外処理状態を変更する可能性があります。例外処理状態の変更は以下のような場合に起こることがあります。
- コンストラクタが実行された。
- デストラクタが実行された。
- try/catch ブロックに入った。
- try/catch ブロックから出た。
例外処理状態が変更されると、例外ハンドラが呼び出されず、変数が正しく作成または破棄されなくなることがあります。このような場合には、エディット・コンティニューの警告が発生します (警告ENC2003)。
クラス、構造体、共用体、列挙定義を含む新しいデータ型の追加、またはデータ型の変更
データ型は実行可能ファイルの固定セクションに格納されています。Visual C++ 6.0 では、実行可能ファイルをリビルドすることなく、グローバルに追加や変更を行うことはできません。
新しい関数プロトタイプの追加、関数の削除、または関数プロトタイプの変更
データ型は実行可能ファイルの固定セクションに格納されています。関数シグニチャはデータ型であり、実行可能ファイルをリビルドすることなく追加や変更を行うことはできません。エディット・コンティニューは、実行可能ファイルのビルド時に同じ形の関数プロトタイプが存在していた場合に限って、ソース コードへの新しい関数の追加をサポートしています。関数の削除はデータ型の変更を必要としませんが、やはり許されていません。これは、他の未変更のファイルがその関数を参照している場合に、再コンパイルが必要であるということを検出できないからです。関数プロトタイプの変更はサポートされていません。これは本質的に、古い関数を削除して新しい関数を追加するという操作であり、関数の削除が許容されていないためです。
グローバルまたは静的コードへの大部分の変更
グローバルおよび静的コードは実行可能ファイルの固定セクションに格納されています。実行可能ファイルをリビルドすることなくグローバルに変更することはできません。
別のマシンからコピーされ、ローカルにビルドされていない実行可能ファイルの変更
コードに対する変更を適用するときに、エディット・コンティニューはオリジナルのソース コード、.pdb ファイル、およびコンパイラが実行可能ファイルの生成に使用したパスをそのままの形で使用します。この情報は、各ソース ファイルの .obj モジュールに格納されています。エディット・コンティニュー操作の際に、これらのパスが間違っていると、エディット・コンティニューは実行に失
敗します。
関数コール スタック上にある関数に対する一部の変更
エディット・コンティニューは、コール スタック上にある関数に対して、一部のコード変更を動的に適用することができません。これらの関数は [コール スタック] ウィンドウに表示されています。この種のコード変更の例としては、現在実行中の関数に、64 バイトを超える新しい変数を追加するというような操作があります。エディット・コンティニューは、コール スタック上の関数には、新しい変数を 64 バイトまでしか追加できません。エディット・コンティニューがこれらのアクティブな関数にコードの変更を適用できなかった場合には、[エディット・コンティニュー コール スタック] ダイアログ ボックスが表示されることがあります (詳細については、「ヒントとトリック」のセクションを参照)。このときには、関数のオリジナル コードが実行され、デバッグは [混合モード] ウィンドウでしか行えません。コール スタックの一番上に達した関数にコードの変更が適用できなかった場合には、次に関数が呼び出された時点で適用されます。コードの変更が意図的に行われたものである場合には、[エディット・コンティニュー コール スタック] ダイアログ ボックスで [はい] を選択します。
詳細については、「ヒントとトリック」と、「エディット・コンティニューのツアー」の「再帰関数の変更」のセクションを参照してください。
コール スタック上の関数への 64 バイトを超える新しい変数の追加
エディット・コンティニューは、関数への新しい変数の追加をサポートしています。コール スタック上にない関数への新しい変数の追加には、メモリの制限はありません。しかし、コール スタック上の関数呼び出しについては、64 バイトのスタック フレーム メモリ パッドが存在しています。これらの関数は [コール スタック] ウィンドウに表示されています。コール スタック上の関数に 64 バイトを超える新しい変数が追加されると、エディット・コンティニューは [コール スタック] ダイアログボックスを表示します。ユーザーがこのダイアログ ボックスで[はい] を選択すると、関数のオリジナル コードが実行され、関数のデバッグは、次に呼び出されるまでは [混合モード] ウィンドウでしか行えなくなります。次に呼び出しが行われた時点で、コードの変更が適用されます。詳細につ
いては、「ヒントとトリック」のセクションを参照してください。
作成または破棄を必要とする新しいローカル変数の追加
エディット・コンティニューは、オブジェクトが作成または破棄を必要としない限り、関数への新しい C++ クラス オブジェクト変数の追加をサポートしています。たとえば、オブジェクトが実行ポイントの前でインスタンス作成されており、クラス オブジェクトがコンストラクタの呼び出しを必要としていると、実行ポイントはコンストラクタ呼び出しをすでに過ぎているので、呼び出しを実行することができません。この場合、エディット・コンティニューは [コール スタック] ダイアログ ボックスを表示します。このダイアログ ボックスでユーザーが [はい] を選択すると、関数のオリジナル コードが実行され、関数のデバッグは、次に呼び出されるまでは [混合モード] ウィンドウでしか行えなくなります。次に呼び出しが行われた時点で、コードの変更が適用されます。詳細については、
「ヒントとトリック」のセクションを参照してください。
使用されていないデータ型。ビルド時に定義されていた場合も含む
ソース コードの中の、C++ クラスなどを含む一部のデータ型は、実行可能ファイルのビルド時にソース コードの中でそのデータ型の変数が宣言されていなければ、実行中のアプリケーションには取り込まれません。使用されていないデータ型は、ディスクとメモリのスペースを節約するために、リンカによって実行可能ファイルから除外されます。デバッグ中に、この種のデータ型の新しい変数を関数に追加して、エディット・コンティニューを起動すると、そのデータ型は定義されていないので、次の警告とエラーが発生します。
コンパイル中...
EC_Demo.cpp
C:\Src\EC_Demo.cpp(10) : warning C4655: 'pListClass' : 変数の型が前回のビルドから新規に追加されているか、他の個所で異なる定義がなされています。
C:\Src\EC_Demo.cpp(14) : fatal error C1092: 新しいデータ・関数型はエディット・コンティニューでサポートされていません。ビルドが必要です
D:\vs98\VC98\BIN\cl.exe の実行エラー
エディット・コンティニュー - エラー 1 ,警告 1
50 個以上のソース ファイルの再コンパイルが必要となる変更
エディット・コンティニューは、1 回の操作で 50 個を超えるファイルにはコードの変更を適用することができません。1 回のエディット・コンティニュー操作で 50 個を超えるファイルを再コンパイルする必要が生じると、エディット・コンティニューはエラーを発行します。コードを変更するためにはビルドを行う必要があります。
すでに 2 回以上定義されている名前を持つ変数の追加または削除
コードの変更に、1 つの関数の中ですでに 2 回以上(別々のスコープで)定義されている名前を持つ変数の追加または削除が含まれていると、エディット・コンティニューは関数または関数コールスタックの呼び出しにコードの変更を適用することができません。これらの呼び出しは [コール スタック] ウィンドウに表示されています。エディット・コンティニューは、関数の実行中は、このような変数の追加または削除を行うことができません。この場合には、関数のオリジナル コードでのデバッグが続けられ、コードの変更は関数が次に呼び出された時点で適用されます。
プロジェクトへの新しいソース ファイルの追加
デバッグ中に、プロジェクトに新しいソース ファイルを追加した後に、コードの変更を適用すると、エディット・コンティニューは次の警告を発します。
エディット・コンティニュー: warning ENC2005:新しいソースはコードに変更を与えます。デバッガの行番号に対する影響があるかもしれません:
このようなコードの変更には、最後のビルドで参照されていなかったソース ファイルが関与しています。この際には、新しく参照されたソース ファイルをデバッグしているときに、一部のデバッガ機能に影響が及びます。新しいコードにブレークポイントを設定することはできませんし、たとえば [カーソルの前まで実行] を使うことができません。他のソース ファイルについては、すべてのデバッガ機能が使用できます。すべてのソース ファイルでデバッガの全機能を使えるようにするには、デバッギングを中止して、ビルドを行ってください。
静的にリンクされたライブラリの中のコードの変更
コードの変更に、スタティック ライブラリ (.lib) からリンクされたコードが関与している場合、エディット・コンティニューは次の警告を発します。
エディット・コンティニュー: warning ENC2502: module はエディット・コンティニューの対応できないライブラリとリンクされています。
エディット・コンティニューは、ライブラリの中のコードへの変更はサポートしていません(DLLを除く)。ライブラリ (.lib) はビルドの際に実行可能ファイルにリンクされます。現時点では、スタティックライブラリのコードを変更するためには、再リンクを行う必要があります。デバッギングを中止して、ビルドを行って、コードの変更を適用してください。
エディット・コンティニューのパフォーマンス
速度のメトリックス
エディット・コンティニューは、デバッグ中のコードの変更に要する時間を大幅に短縮します。次の表に、デバッギング セッションの中で、Microsoft Foundation Class (MFC) AppWizard で生成した MainFrm.cpp を変更したときの所要時間を示します。ファイルのサイズは 2,521 バイトでした。測定は、32 MBの RAM を搭載し、Microsoft Windows NT(R) 4.0 SP3 を実行している Pentium 90-MHz マシンで行われました。これは AppWizard で生成された MFC EXE アプリケーションの典型的な数値です。
| エディット・コンティニューを使用しない場合
| 時間
| デバッギングの中止に要する平均時間
| 1.42 秒
| 再コンパイルに要する平均時間
| 0.49 秒
| 再リンクに要する平均時間
| 2.54 秒
| デバッギングの再開に要する平均時間
| 9.50 秒
| 前回の実行ポイントまでのナビゲートに要する平均時間
| 11.00 秒
| エディット・コンティニューを使用しない場合の平均時間
| 24.95 秒
| | | | | | |
エディット・コンティニューが有効になっていない場合、ファイルを再コンパイルし、実行可能ファイルをリビルドし、デバッガを前回の実行ポイントまでナビゲートするのに 25 秒弱が必要でした。エディット・コンティニューが有効になっていると、1 秒以内で同じ状態にすることができます。
| エディット・コンティニューを使用する場合
| 時間
| 再コンパイルに要する平均時間
| 0.49 秒
| メモリ イメージへのコードの変更の適用に要する平均時間
| 0.47 秒
| エディット・コンティニューを使用する場合の平均時間
| 0.96 秒
| | | |
この例からわかるように、MFCを使用する開発者 (Visual C++ を使用する開発者の 75 %以上がMFCを使用しています) の典型的な例では、エディット・コンティニューを使った場合に、コードの変更と適用のサイクルが約25倍も高速化されています。このように、効率が劇的に改善され、貴重な開発リソースをより重要な目的に振り分けることが可能になっています。
ファイル サイズのメトリックス
エディット・コンティニューが有効になっていると、全体的なファイル サイズが若干増加します。次に、AppWizard で生成された MFC EXE アプリケーションでの、エディット・コンティニューのファイルの違いを示します。
| ファイル
| エディット・コンティニューを有効にしたときのバイト サイズ
| エディット・コンティニューを無効にしたときのバイト サイズ
| エディット・コンティニューのバイト サイズの違い
| EC_Demo.pch
| 5,488,860
| 5,496,816
| -7,956 (小さい)
| EC_Demo.res
| 10,716
| 10,716
| 0 (違いなし)
| Vc60.pdb
| 364,544
| 364,544
| 0
| Vc60.idb
| 205,824
| 205,824
| 0
| StdAfx.obj
| 105,345
| 104,885
| 460 (大きい)
| ChildFrm.obj
| 15,878
| 12,399
| 3,479
| EC_DemoDoc.obj
| 14,403
| 10,768
| 3,635
| MainFrm.obj
| 18,642
| 14,354
| 4,288
| EC_DemoView.obj
| 19,629
| 14,384
| 5,245
| EC_Demo.obj
| 23,298
| 17,829
| 5,469
| EC_Demo.pdb
| 336,896
| 328,704
| 8,192
| EC_Demo.ilk
| 326,068
| 315,964
| 10,104
| EC_Demo.exe
| 122,930
| 57,394
| 65,536
| Totals:
| 7,053,033
| 6,954,581
| 98,452 (大きい)
| | | | | | | | | | | | | | |
要約すると、エディット・コンティニューを有効にしても、デフォルトの AppWizard が生成するMFCEXEアプリケーションでは、98 KB しかサイズが増大しません。
エディット・コンティニューが有効なケース
エディット・コンティニューは、サポート対象のコード変更が行われたときには、つねに利用する価値があります。何度か使用すれば、どのようなコード変更がサポートの対象となっているか、またどのようなコード変更でビルドが必要かは簡単に覚えることができます。エディット・コンティニューを便利に使うヒントについては、次のセクション「ヒントとトリック」を参照してください。
ヒントとトリック
アプリケーションの実行中のコードの変更の適用
バグは、ユーザーがソース コードをステップしているときに、最もよく見つかります。ステップを行っているとき、デバッガは「ブレーク」状態にあります。つまり、デバッグ対象のアプリケーションは実行中ではありません。エディット・コンティニューは、Visual C++ が「ブレーク」状態にあるときに最も頻繁に使用されます。
初期のユーザビリティ テストによると、一部のユーザーはアプリケーションの実行中にバグを発見していました。この場合、エディット・コンティニューを使ってバグを修正するためには、VisualC++ にフォーカスを切り替え、[デバッグ] メニューから [ブレーク] を選択し、コードに変更を加え、エディット・コンティニューを起動した後に、[デバッグ] メニューから [実行] を選択して、デバッグ対象のアプリケーションの実行を再開しなくてはなりません。
このステップの多さを解消するために、[コードに対する変更を適用] コマンドは、デバッグ対象のアプリケーションが実行中であっても呼び出せるようになっています。アプリケーションの実行中に、Visual C++ にフォーカスを切り替えて、コードに変更を加えます。その後、[コードに対する変更を適用] コマンドを呼び出せば、コードの変更はブレークを実行しなくても適用されます。デバッグ対象のアプリケーションは単に実行を続けますが、コードの変更は適用されています。エディット・コンティニューがそのコード変更をサポートしていない場合には、エラーが報告されますが、デバッグ対象のアプリケーションは実行を続けます。
外部プロジェクトのコードの変更
エディット・コンティニューは、現在ロードされているプロジェクト以外のファイルのコード変更にも対応しています。コードの変更は、エディット・コンティニューに対応してビルドされた任意の実行中のコードに適用できます。一般に、デバッグを行えるコードであれば、エディット・コンティニューを利用することができます。これは、エディット・コンティニューを有効にしてビルドされたEXE、DLL、COM コンポーネント、および ActiveX(R) コントロールに当てはまります。
たとえば、ダイナミック リンク ライブラリ (DLL) の中の関数を呼び出すEXEをデバッグしているとしましょう。DLL のプロジェクト ワークスペースが Visual C++ にロードされていなくても、DLL にコードの変更を適用することができます。単に、その DLL の一部であるソース ファイルを開き、コードを変更して、[コードに対する変更を適用] を選択してください。DLL は、デバッギング セッションの終わりに、コードの変更にマッチするように自動的に再リンクされます。
[次に実行するステートメント]
バグは、すでにステップ オーバーを行った後に発見されることがよくあります。実行ポイントが問題を含んでいるソース コードを通り過ぎている場合、それを含んでいる関数がもう一度呼び出されるのを待つという以外に、エディット・コンティニューで適用されたコード変更の結果を確認するにはどうすればいいのでしょうか?
#include
void main()
{
char* pszName = "David"; // Name string
char buffer[6]; // Buffer for above name + null
int iCount; // Loop counter
for (iCount=0; iCount<5; iCount++) // Loop five times
{
buffer[iCount] = pszName[iCount];
}
printf("The name in the buffer is %s.\n", buffer);
}
例として、上の関数をステップしているときにバグを発見したとします。実行ポイントが printf() 関数呼び出しに達したときに、バッファ文字列の末尾にnull文字を追加するためには、ループを 5 回ではなく 6 回実行する必要があることに気づいたのです。このときには、数値を5から 6 に変更し、[コードに対する変更を適用] コマンドを呼び出せば、実行中のアプリケーションの中のバグは修正されます。しかし、これを確認するにはどうすればいいのでしょうか? また、バグが非常に重大なもので、バグがすでに実行されたために、アプリケーションが間もなくクラッシュするというような場合にはどうすればいいのでしょうか? 多くの人が、デバッグを中止して、リビルドを行いたいという誘惑にかられるでしょう。しかし、[次に実行するステートメント] コマンドを使えば、リビルドは必ずしも必要ではありません。
エディット・コンティニューでコードの変更を適用した後に、for ループ(上の例では 8 行目) の上でマウスを右クリックします。コンテキスト メニューから [次に実行するステートメント] を選択します。実行ポイントがforループに戻ったことに注意してください。これで、通常どおりにループのソースコードをステップし、バグが修正されたことを確認することができます。
コードの変更の際に初期値が変更された場合には、[次に実行するステートメント] を使って、初期化ステートメントの箇所に実行ポイントを移動します。たとえば、上の例で、pszName を新しい値に再初期化したい場合には、実行ポイントを 4 行目に設定します。
[次に実行するステートメント]はプログラムの実行を取り消すのではなく、実行ポイントを移動するだけです。変数の中には作成と破棄を必要とするものがありますが、[次に実行するステートメント]はこれらの操作をバイパスする可能性があることに注意してください。[次に実行するステートメント] を使うと、実行ポイントを別の関数に移動することができますが、一般にこれを行うと、関数が返った後にアプリケーションがクラッシュします。
[コール スタック] ウィンドウの中の、変更の適用外のコードを含んでいる関数の色の変更
関数が自分自身を呼び出した場合、または 1 つの関数が何度も呼び出されて実行されている場合、Visual C++ が「ブレーク」状態にあるときには、[コール スタック] ウィンドウの中にそれぞれの呼び出しが表示されます。エディット・コンティニューが起動されたとき、コードの変更は、コールスタックの一番上にある関数呼び出しにしか適用できません。コードの変更がまだ適用できない関数呼び出しは、他の関数とは異なる色(デフォルトでは灰色)で表示されます。次の [コール スタック] ウィンドウの図に例を示します。

図 9.
この色をカスタマイズするには、[ツール] メニューの [オプション] を選択します。右の方にスクロールして、一番右の [書式] というタブを選択します。[カテゴリ]リスト ボックスから [コール スタックウィンドウ] を選択し、[代替コード] の色を変更します。
複数のモニタの利用
Visual C++ 6.0 では複数のモニタがサポートされています。複数のモニタをサポートしているオペレーティング システム(Windows 98およびWindows NT 5.0オペレーティング システムを含む)上で Visual C++ 6.0 を実行しているときには、デバッグ対象のアプリケーションを1 つのモニタに表示し、Visual C++ IDE(およびデバッガ) を別のモニタに表示することができます。エディット・コンティニューを使えば、1 つのモニタでコードを変更した結果が、別のモニタ上の実行可能ファイルに反映されます。
[混合モード] ウィンドウがフォーカスを受け取った後の操作
[コール スタック] ウィンドウの中の関数にコードの変更が適用できないときには、関数のオリジナル コードを実行する必要があります。関数のソース コードはすでにユーザーによって変更されているので、関数が返るまで実行しなくてはならない関数のオリジナル コードにはもはや対応していません。関数のオリジナル コードを表示する唯一の選択肢が、逆アセンブル コードです。この場合、エディット・コンティニューはユーザーが関数のオリジナル コードをデバッグできるように、[混合モード] ウィンドウにフォーカスを与えます。[混合モード] ウィンドウでは、関数のオリジナルのソース コードの行が、それを実行するアセンブリ命令とともに表示されています。このウィンドウの中でもデバッガ コマンドを使用することができます。実行ポイントが RET 命令を通り過ぎるまで、ステップ オーバー (F10) を行うことをお勧めします。RET 命令は、現在の関数から返ることを指示します。いったん関数から返ったら、実行ポイントを右クリックし、コンテキスト メニューから [ソースを表示] を選択します。実行ポイントに対応するソース コード行が存在していれば、フォーカスは [混合モード] ウィンドウからソース コードに戻ります。その後は、通常どおりにソースコードのデバッグを続けることができます。
実行ポイントが正しく配置されなかったときの操作
稀なケースですが、実行ポイントが間違った位置に置かれることがあります。この場合には、次のメッセージが表示されます。

図 10.
実行ポイントが間違った位置に置かれた場合には、[次に実行するステートメント] コマンドを使って手動で移動する必要があります。その後は、通常どおりにデバッギングを続行することができます。詳細については、「[次に実行するステートメント]」を参照してください。
自動再リンクを無効にする
エディット・コンティニューは、デバッギング セッション内でエディット・コンティニュー操作が成功すると、そのセッションの後に実行可能ファイルを自動的に再リンクします。デバッグ対象の実行可能ファイルが、ビルドの際とは異なる場所に置かれていた場合、エディット・コンティニューはオリジナルのビルド位置だけで再リンクを行い、デバッグ対象の位置では再リンクを行わなかったことを知らせる警告を発します。
デバッグ中の変更をもとに "F:\testprj\test1221\Debug\test1221.exe" を再リンクしています...
エディット・コンティニュー : warning ENC2501: この実行ファイルは、
(C:\Src\EC_Demo\Debug\EC_Demo.exe) でビルドされていますが、
デバッグされていた場所 (C:\TEMP\EC_Demo.exe) とは異なっています。
C:\Src\EC_Demo\Debug\EC_Demo.exe - エラー 0 ,警告 1
ユーザーによっては自動再リンクを無効にしたいことがあるでしょう。再リンクを無効にすると、実行可能ファイルはソース ファイルと同期されなくなり、実行可能ファイルのデバッグ情報がソースコードの行と対応しなくなる可能性があります。エディット・コンティニューの自動再リンクを無効にするには、Microsoft Windows の RegEdit.exe ツールを使って、次のレジストリ キーの値を 0 に設定します。この操作はバージョン 6.0 以降の Visual C++ でも動作するという保証はありません。
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Debug\ENCRelink
ヘッダー ファイル編集サポートによって引き起こされる遅延の解消
エディット・コンティニューを有効にしてデバッグを行っていると、ヘッダー ファイルを編集しているとき、またはエディット・コンティニューを有効にしてコンパイルされなかったソース ファイルを編集しているときに遅延が生じることがあります。この遅延の長さは、デバッグしているプロジェクトのサイズに比例します。これは、エディット・コンティニューがプロジェクトの .idb ファイルをロードして、編集されたファイルにどのソース ファイルが依存しているか、編集の結果として再コンパイルが必要かを判断していることが原因です。この動作を無効にするには、プロジェクトの .idb ファイルの名前を変更する、移動する、または削除するか、Microsoft Windows の RegEdit.exe ツールを使って、次のレジストリ キーの値を 0 に設定します。これにより、エディット・コンティニューはヘッダー ファイルのコードに変更を適用できなくなります。この操作はバージョン6.0 以降の Visual C++ でも動作するという保証はありません。
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Debug\ENCLoadIdbFiles
リッチなエディット・コンティニュー診断情報の表示
エディット・コンティニュー エンジン (msenc10.dll) と Visual C++ デバッガ パッケージ (devdbg.pkg) は、リッチなエディット・コンティニュー診断情報を提供する能力を持っています。エディット・コンティニュー操作の際に表示される情報のレベルは、レジストリ内の設定によって決定されます。Microsoft Windows の RegEdit.exe ツールを使って、次のレジストリ キーの値を目的のトレース レベルに設定することができます。Windows レジストリの編集は、Windows とインス
トールされているソフトウェアの動作に大きな影響を与える可能性があるので、慎重に行う必要があります。また、この操作はバージョン6.0 以降の Visual C++ でも動作するという保証はありません。
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Debug\ENCTraceLevel
| トレース レベル
| エディット・コンティニューの際に表示される診断情報
| 0
| フィードバックなし
| 1
| エディット・コンティニューのメッセージとエラーのみ
| 2 (デフォルト)
| エディット・コンティニューのメッセージ、エラー、および警告
| 3
| 詳細なトレース情報と、エディット・コンティニューのメッセージ、エラー、および警告
| | | | |
次に、各トレース レベルに対応するメッセージのリストを示します。高いトレース レベルを設定すると、エディット・コンティニューはそれよりも低いレベルのメッセージをすべて表示します。
レベル1のメッセージとエラー
- コードの変更を適用しています….
- シンボルに対するサンクの更新ができません: symbol (loc: location、thunk:
address)
- データ シンボルが変更されています: symbol (symbol)
- 新しい関数に対するサンクのマップができません: function
- packing 型に対する pdb を開けません: pdb (pdb)
- シンボルが名称変更、削除または変更されています: symbol
- グローバルまたはスタティック変数は、追加、名前の変更、削除、またはデータ型または初期化子が変更されました。
- エディット・コンティニューは、このコード変更に対応できません。ビルドが必要です。
- エディット・コンティニューを完了できません。
レベル2(デフォルト) の警告
- ローカル変数が見つかりません: symbol (symbol)
- 新規ローカル変数にはコンストラクタまたはデストラクタが必要です: symbol (symbol)
- コード位置の変更により例外や変数のデストラクション エラーが起きる可能性があります: function
- 既に定義されている名前でローカル変数を追加、削除することはできません: symbol (symbol)
- 新しいソースはコードに変更を与えます。デバッガの行番号に対する影響があるかもしれません: function (function)
- filename を作成できません。
- この実行ファイルは、(location) でビルドされていますが、デバッグされていた場所(location) とは異なっています。
- module はエディット・コンティニューの対応できないライブラリとリンクされています。
- module が見つかりません。
- object file と対応する実行ファイルが一致しません。
- source file に加えられた変更を無視します。
- プログラムは実行されませんでした。(原因: explanation)。
- コール スタック上の関数にコードの変更を適用できませんでした。
レベル3のトレース情報 (一部はアウトプットウィンドウの [デバッグ] ペインに表示されます)
- エディット・コンティニュー操作を開始します。
- オブジェクトを挿入します: module.
- コードの変更を適用します。
- エディット・コンティニュー操作をキャンセルします。
- アクティブなコードの変更を全て削除します。
- エディット・コンティニューを初期化しました。
- プロキシとして PDB を開きます: pdb.
- エラー error が報告されました。
- エラー error が発生しました。
- Symbol (number) : エラー error が発生しました。
- number バイト addressに書き込みます。
- エディットされたセクション: symbol.
- public シンボルが見つかりません: symbol.
- サンクに対する fixup : symbol (関数: function, サンク: address).
- シンボルに対するサンクを更新しました: symbol (関数: function, サンク: address).
- symbol (time) の経過時間
- セクションを置換することはできません symbol: symbol (サイズ: size).
- PDB インターフェースはエディット・コンティニューをサポートしていません
- 新しい関数をデバッグ対象に追加しています: symbol (関数: function サンク: thunk).
- 重複する comdat を無視します: symbol (symbol).
- PDB 内にタイプ ID が見つかりません - タイプ typeを無視します。
- 関数のシグネチャが変更されました: function.
- スタック フレームのサイズが変更されました: symbol.
- ユーザ定義のタイプが見つかりません: symbol.
- 上位関数の名前が変更されました: function.
- 前のオブジェクト ファイルが開けません: module.
- OBJ 処理中のエラーです: module.
- オジェクトからのセクションのマップができません: module.
- エクスポート用に lib(dll) を追加しました: symbol (symbol).
- インポート ライブラリを使用してシンボルを解決しました: symbol.
結論
本記事が、Visual C++ 6.0 のエディット・コンティニュー機能を最大限に活用するための重要な情報を提供できたことを願っています。エディット・コンティニューの優れた面の 1 つが、この機能が革命的であることを知っているかどうかを問わず、Visual C++ のほぼすべてのユーザーに役立つということです。この結果として、よりスムーズで中断の少ない、一般的に生産性の高い開発が可能になります。少なくとも Microsoft 社内では、社内のありとあらゆる開発者たちから、エディ
ット・コンティニューに寄せる感謝の声を伝える電子メールが届いています。しかし、これは典型的なユーザー集団とはいえないので、次にトレード ショーやコンファレンスで Visual C++ のチーム メンバに会ったときには、エディット・コンティニューをどのように使っているか、これによって開発のプロセスがどのように変わったかをぜひ教えてください。