VC6でconst intが変な値になる? – プログラミング – Home

VC6でconst intが変な値にな...
 
通知
すべてクリア

[解決済] VC6でconst intが変な値になる?

固定ページ 1 / 2

え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

あるライブラリがコンパイルした環境によって返す値が異なって困っていました
原因は、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で宣言すると期待通りに動作します


引用未解決
トピックタグ
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> これは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が当たってないことをどうやって確認できたっけ?


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

ちょっと気になったこと、「13107回ループが回らない」とありますけれど、
では、いったい何回回っているんでしょう?

あと、少なくとも私はそういう現象にあったことは有りません。


返信引用
ん?
 ん?
(@ん?)
ゲスト
結合: 17年前
投稿: 25
 

実際にたいいちろうさんのソースでやってみた。
data 0x00003333
count 0x036f03e0
i 0x036f03e0
ほぉー…。

コンパイル時にワーニングが出てました。
warning C4244: 'initializing' : 'const double' から 'const int' に
変換しました。データが失われているかもしれません。


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

>たいちう様

ダイアログベースのアプリを作って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に大きな値が入りました


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

># SPが当たってないことをどうやって確認できたっけ?

レジストリエディタで
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0

の下にサービスパックがあたっているとServicePacksができていてその中にSPの値が記述
されます


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

>PATIO様

値は大きな値なんですが、そのときによって違うので、不定です


返信引用
ん?
 ん?
(@ん?)
ゲスト
結合: 17年前
投稿: 25
 

追記
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)を比較してますね。


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

>ん?様
ワーニングができていることはわかっています
が、65535と0.2の演算はdoubleで行われて、const intにキャストされるので65535*0.2は
整数型で13107なので、13107が格納されることを期待しています


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

すいません
コードが間違っていました

const int data2 = 65535 * 0.2;//data2でなくてdataです
int time = 0;
for(int i = 0; i < data; i++){
time++;
}


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> レジストリエディタで
> 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のせいではなく、この手の勘違いのせいだと思うのですが。
# 冷静に検証してみてください。


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

>ん?様
dataはconstなので、36F03E0hのところに00003333hとなっているのが正しい姿だと思って
います


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

ホントに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;
にすると、どうなります?


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

>たいちう様

>これは、data と data2 がありますよね。
>実際に試したコードはいかがですか?

元コードを修正していたので、正しい情報が提供できなくてすませんでした

># おそらく、SPのせいではなく、この手の勘違いのせいだと思うのですが。
># 冷静に検証してみてください。

現在、数名で同じ確認をしていますが、まず間違いなくSPの問題だと思っています
SPの修正の情報をネットで調べていますが、いまだ見当たらず・・・


返信引用
え~いち
 え~いち
(@え~いち)
ゲスト
結合: 19年前
投稿: 78
Topic starter  

>たいちう様

const int data = 13107;
const int data = 65535 / 5;

どちらも大丈夫です
ただし、
const int data = 65535 / 5.0;

とするとおかしくなります


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました