プリプロセッサ ブロックを終了すると整数値が変更されます
-
03-07-2019 - |
質問
コードのプリプロセッサ ブロックの最後で変数が変更されているように見えるコードのチャンクがあります。
int initialKeyCount;
#if(DEBUG)
// int initialKeyCount = _root.CountAllKeys();
initialKeyCount = 20000;
#endif
currNode = currNode.EnsureDegreeKeysPresent(parent); //initialKeyCount = 19969 here
#if(DEBUG)
int currentKeyCount = _root.CountAllKeys();
Debug.Assert(initialKeyCount == currentKeyCount,
string.Format("EnsureDegreeNodesPresent changed the node count from {0} to {1}.", initialKeyCount, currentKeyCount));
#endif
デバッガーでこれを実行すると、おそらく 20000 が割り当てられた後、initialKeyCount = 19969 になります。これを少し試してみたところ、最初のプリプロセッサ ブロック内では、initialKeyCount への割り当ては正しいことがわかりました。しかし、コードが最初のプリプロセッサ ブロックを離れるとすぐに、値は魔法のように 19969 に変わります。
この動作は、変数が最初のプリプロセッサ ブロックの内側で宣言されているか外側で宣言されているかに関係なく同じです。値は 2 番目のプリプロセッサ ブロック内では 19969 のままです。
プリプロセッサ ブロック内で行われた割り当ては、そのブロックの外では未定義ですか?それは間違っているように思えますが、ここで起こっていることのようです。
解決
Visual Studioのような音は混乱しました。これらの手順を順番に試してください
- クリーンコマンドを使用
- Visual Studioを再起動します
- リモートでもプログラムのように見えるすべてのDLLおよびEXEを削除します
- すべてのBINおよびOBJフォルダーを再確認して、見逃していないかどうかを確認します。
- リモートでもプログラムのように見えるDLLおよびEXEをハードドライブ全体で検索し、それらも削除します
以前、私が働いていたIT会社でこれを週に一度見ていました。通常、同じプロジェクトのコピーが複数ある場合に発生しますが、それがなくても見たことがあります。
他のヒント
この種の動作は、デバッガが編集中のソースコードと一致しないコードを実行しているように聞こえます。ソースの変更が、実行中のコードに至るまで確実に行われていると確信していますか?
プリプロセッサブロックは言語構文とは無関係です。したがって、プリプロセッサブロックは変数定義の範囲に影響を与えないと言うのは正しいことです。
Greg Hewgillに同意します-このようなことは以前に見たことがあります。
また、デバッガーが使用しているアセンブリを見つけて、Reflectorで開きます。分解することで、実際に何が起こっているかをよりよく理解できるはずです。
このような問題に直面したときは、アセンブリレベルで見てください。
アセンブリは、最近ではほとんどコーディングしないものですが、必要にして、このような謎を突き止めることができます。
物事はどんどん奇妙になっていきます。上記の提案に従って、Reflector を使用したコードとデバッガーによって提供される逆アセンブリを調べました。どちらも期待どおりに見えます。変数の「魔法の」変化を明確に示すために、コードを少し変更しました。
新しいコードは
int initialKeyCount;
#if(DEBUG)
// int initialKeyCount = _root.CountAllKeys();
initialKeyCount = 20000;
initialKeyCount++;
initialKeyCount = initialKeyCount;
#endif
currNode = currNode.EnsureDegreeKeysPresent(parent);
#if(DEBUG)
int currentKeyCount = _root.CountAllKeys();
Debug.Assert(initialKeyCount == currentKeyCount,
string.Format("EnsureDegreeNodesPresent changed the node count from {0} to {1}.", initialKeyCount, currentKeyCount));
#endif
上記の分解は、
int initialKeyCount;
#if(DEBUG)
// int initialKeyCount = _root.CountAllKeys();
initialKeyCount = 20000;
00000094 mov dword ptr [ebp-50h],4E20h
initialKeyCount++;
0000009b inc dword ptr [ebp-50h]
initialKeyCount = initialKeyCount;
0000009e nop
#endif
currNode = currNode.EnsureDegreeKeysPresent(parent);
0000009f mov edx,dword ptr [ebp-48h]
...
メモリウィンドウを使用して、IPが
00000094 の値は 0x0 です
0000009b の値は 0x4e20 です
0000009e の値は 0x4e21
0000009f の値は 0x4e01
アセンブリ コードを書いてから長い時間が経っていることは認めますが、nop はメモリに書き込むべきではないと確信しています。:)
明らかに、デバッガに表示されていないコードが実行されています。私のプリプロセッサの使用方法に何か問題があり、これが原因なのか、それとも単なるバグなのか、知っている人はいますか?