あるライブラリがコンパイルした環境によって返す値が異なって困っていました
原因は、VC++6.0のサービスパックが古い(SP4以降だと正しく動くようです)と起こるよ
うです
const int data = 65535 * 0.2;
としたいときにdataには13107が格納されると思うのですが、デバッカでとめて変数を確
認しても、&dataのアドレスに書かれている数値を見ても、13107になっています
しかし、この変数を使うとおかしなことがおきます
・文字列への変換(CString::Format()を使用)
・ループを回す
for(int i = 0; i < data; i++){
//13107回ループが回らない
}
これはVC6のバグだと思っていいんですよね?
ちなみに、宣言のconstをとってintで宣言すると期待通りに動作します
> これはVC6のバグだと思っていいんですよね?
> ちなみに、宣言のconstをとってintで宣言すると期待通りに動作します
(多分)SPなしのVC++6ですが再現しません。
再現できるコードを示すことができますか?
BOOL CMy0205Doc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
const int data = 65535 * 0.2;
TRACE(data = %d\n, data);
int count = 0;
for (int i = 0; i < data; i++)
count++;
TRACE(count = %d\n, count);
CString str;
str.Format(%d, data);
TRACE(str = %s\n, str);
return TRUE;
}
# SPが当たってないことをどうやって確認できたっけ?
ちょっと気になったこと、「13107回ループが回らない」とありますけれど、
では、いったい何回回っているんでしょう?
あと、少なくとも私はそういう現象にあったことは有りません。
実際にたいいちろうさんのソースでやってみた。
data 0x00003333
count 0x036f03e0
i 0x036f03e0
ほぉー…。
コンパイル時にワーニングが出てました。
warning C4244: 'initializing' : 'const double' から 'const int' に
変換しました。データが失われているかもしれません。
>たいちう様
ダイアログベースのアプリを作ってOnInitDialogの中で
const int data = 65535 * 0.2;
CString str;
str.Format(%d, data);
this->SetDlgItemText(IDC_EDIT1, str);
としてみました。IDC_EDIT1はエディットボックスでとんでもない値が表示されました
また、コンソールアプリで
const int data2 = 65535 * 0.2;
int time = 0;
for(int i = 0; i < data; i++){
time++;
}
とやったらtimeに大きな値が入りました
># SPが当たってないことをどうやって確認できたっけ?
レジストリエディタで
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0
の下にサービスパックがあたっているとServicePacksができていてその中にSPの値が記述
されます
>PATIO様
値は大きな値なんですが、そのときによって違うので、不定です
追記
179: int count = 0;
00401CCB mov dword ptr [ebp-18h],0
180: for (int i = 0; i < data; i++) {
00401CD2 mov dword ptr [ebp-1Ch],0
00401CD9 jmp CBbDlg::OnButton1+64h (00401ce4)
00401CDB mov eax,dword ptr [ebp-1Ch]
00401CDE add eax,1
00401CE1 mov dword ptr [ebp-1Ch],eax
00401CE4 cmp dword ptr [ebp-1Ch],36F03E0h ←ここ
00401CEB jge CBbDlg::OnButton1+78h (00401cf8)
181: count++;
00401CED mov ecx,dword ptr [ebp-18h]
00401CF0 add ecx,1
00401CF3 mov dword ptr [ebp-18h],ecx
182: }
00401CF6 jmp CBbDlg::OnButton1+5Bh (00401cdb)
183: TRACE(count = %d\n, count);
混合モードで見るとここでi値とdata値(=36F03E0h)を比較してますね。
>ん?様
ワーニングができていることはわかっています
が、65535と0.2の演算はdoubleで行われて、const intにキャストされるので65535*0.2は
整数型で13107なので、13107が格納されることを期待しています
すいません
コードが間違っていました
const int data2 = 65535 * 0.2;//data2でなくてdataです
int time = 0;
for(int i = 0; i < data; i++){
time++;
}
> レジストリエディタで
> HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0
>
> の下にサービスパックがあたっているとServicePacksができていてその中にSPの値が記述
> されます
ありがとうございます。当方、SP6があたってました。勘違いです。
> ダイアログベースのアプリを作ってOnInitDialogの中で
> ...
> としてみました。IDC_EDIT1はエディットボックスでとんでもない値が表示されました
これは再現しませんでした。
> また、コンソールアプリで
>
> const int data2 = 65535 * 0.2;
> int time = 0;
> for(int i = 0; i < data; i++){
> time++;
> }
> とやったらtimeに大きな値が入りました
これは、data と data2 がありますよね。
実際に試したコードはいかがですか?
# おそらく、SPのせいではなく、この手の勘違いのせいだと思うのですが。
# 冷静に検証してみてください。
>ん?様
dataはconstなので、36F03E0hのところに00003333hとなっているのが正しい姿だと思って
います
ホントにVCのバグのような気もしてきた。
私の環境(VC6 + SP6)では、ん?さん掲示の部分(+α)は、
次のようになる。
125: const int data = 65535 * 0.2;
00401973 mov dword ptr [ebp-1Ch],3333h
126: TRACE(data = %d\n, data);
0040197A push 3333h
0040197F push offset string data = %d\n (00415114)
00401984 call AfxTrace (00401124)
00401989 add esp,8
127:
128: int count = 0;
0040198C mov dword ptr [ebp-20h],0
129: for (int i = 0; i < data; i++)
00401993 mov dword ptr [ebp-24h],0
0040199A jmp CMy0205_2Dlg::OnInitDialog+115h (004019a5)
0040199C mov edx,dword ptr [ebp-24h]
0040199F add edx,1
004019A2 mov dword ptr [ebp-24h],edx
004019A5 cmp dword ptr [ebp-24h],3333h
004019AC jge CMy0205_2Dlg::OnInitDialog+129h (004019b9)
130: count++;
004019AE mov eax,dword ptr [ebp-20h]
004019B1 add eax,1
004019B4 mov dword ptr [ebp-20h],eax
004019B7 jmp CMy0205_2Dlg::OnInitDialog+10Ch (0040199c)
131: TRACE(count = %d\n, count);
const int data = 65535 * 0.2;
を、
const int data = 13107;
や
const int data = 65535 / 5;
にすると、どうなります?
>たいちう様
>これは、data と data2 がありますよね。
>実際に試したコードはいかがですか?
元コードを修正していたので、正しい情報が提供できなくてすませんでした
># おそらく、SPのせいではなく、この手の勘違いのせいだと思うのですが。
># 冷静に検証してみてください。
現在、数名で同じ確認をしていますが、まず間違いなくSPの問題だと思っています
SPの修正の情報をネットで調べていますが、いまだ見当たらず・・・
>たいちう様
const int data = 13107;
const int data = 65535 / 5;
どちらも大丈夫です
ただし、
const int data = 65535 / 5.0;
とするとおかしくなります