未代入の変数

解決


SPQR  2006-09-14 02:43:07  No: 63005

C++、.NET2003、DXSDK9.0、非MFCです。
flagが非の時に間違って未代入の変数numを使ってしまう以下のようなソースがあります。

int num;
DWORD color;
if( flag ){
num = func();
}else{
//numは何もいじらない
}
if( num < 100 ){
color = COLOR_RED;
}else{
color = COLOR_WHITE;
}

Debugで実行するとnumが未代入と言うRunTimeCheckが出てきて止まってしまいます。それはまだいいのですが、Releaseで実行するハングアップしてしまいます。
例えnumの値が不定であってもハングアップするはずは無い気がするのですが、これが最近のCPUに追加されたXDBitという奴なのでしょうか?また厳密にはDebugもコンパイル時に警告を出すならともかく、実行時に止まれるはずは無い気がするのですが…

それとも何かすごいはずかしい勘違いをしているのでしょうか…


シャノン  2006-09-14 06:51:20  No: 63006

> これが最近のCPUに追加されたXDBitという奴なのでしょうか?

違います。提示されたソースコードから読み取れる限りでは、それは関係ありません。

> また厳密にはDebugもコンパイル時に警告を出すならともかく、実行時に止まれるはずは無い気がするのですが…

コンパイルオプションで止まるように設定しているから止まるのです。それは望んだ挙動というものでしょう。


SPQR  2006-09-14 07:53:01  No: 63007

返答有難うございます。

>コンパイルオプションで止まるように設定
こちらなのですが、そのオプションはどれになるのでしょうか?VC6.0のプロジェクトをコンバートして使っているためたぶん自動で追加されたのだと思いますが、一応望んではいないのです^^;外せるなら外したいと。

またそのオプションはVC6.0の頃は無かったですよね?

あとそのオプションの仕組みはどういうコードで実現されているのかご存知でしたら教えていただけるでしょうか?変数と同じ数のテーブルを用意して未代入フラグとかを立てているのでしょうか?


SPQR  2006-09-14 08:04:47  No: 63008

>ソースコードから読み取れる限りでは、それは関係ありません。
うーん、私もそう思いたい…というか思っていたのですが、そうすると原因は何になるのでしょうか…orz

ちなみに以下のように適当な数を代入するとDebug、Release両方のエラーは消えます。
if( flag ){
num = func();
}else{
num = 1;
}
またReleaseビルドで作ったexeを(IDEを終了して)単体で実行してもハングアップします。

実は1ヶ月前にXDBitに対応したCPUに交換しまして、そのあたりからこの現象が出ているため、それが原因かな?と考えておりました。ただCPU交換前に出ていた気もしますので確信はないのですが…


YuO  2006-09-14 10:55:32  No: 63009

コンパイルオプション/RTCuが有効になっているのでは?


SPQR  2006-09-14 12:44:06  No: 63010

確かにDebug時は/RTC1が指定されていました。これでRunTimeCheckが働くのは正しい動作だということで解決のようです。

ただRelease時はやはり/RTC1や同様の効果を持つ/GZなども定義されていませんでした。またMSDNにもRelease時に指定するとエラーが出ます…のように書いてありましたので、確かに指定されてはないようです。

とすると、やはりなぜ以下のソースでハングアップしたり、直ったりするのか?ということで謎のままのようです。num = 1;で直らないなら、「どっか別の部分にバグがあるんだよ」ということで納得できるのですが…
if( flag ){
num = func();
}else{
//num = 1;
}
if( num < 100 ){


SPQR  2006-09-14 12:48:56  No: 63011

あ、Debug時は解決(納得)しましたが、Release時は解決していない…という趣旨です。すみません。


YuO  2006-09-14 19:04:21  No: 63012

本当にnumへのアクセスがハングアップの原因ですか?
おそらく,別の原因があると思いますが。


PATIO  2006-09-16 00:39:47  No: 63013

YuOさんの意見に一票。
リリースモードでビルドしたものならそこで止まったと言う確証はないでしょうし。
ログを取って確認したと言うのなら話は別ですが。
ハングアップしたのであれば、ハングアップした場所を特定するべきでしょう。
ちなみにデバッグ版ではハングアップしなくてもリリース版ではハングアップすると言うのはよくある話です。
(だから、デバッグ版で動いていても安心は出来無いという事)


SPQR  2006-09-16 03:13:06  No: 63014

止まったのがその関数の以下の部分の前後であることは確認しています。ただアセンブラソースを眺めても最適化が掛かって今一原型をとどめていないため、10〜20命令前後のずれがあるがあるのは確かです。
if( num < 100 ){

あと最初はお二人の言う可能性を疑って徹底的にその部分のソースを見直したのですが、原因が分かりませんでした。特に投稿時に省略したわけではなく、本当に上に上げた部分しかソースがないため困っています。ちなみにその処理はnumの値が減ってきたら文字の色を赤に変えて警告を発すると言うものです。ただしオプションで警告を出さないようになっていたら白のままという感じです(if( flag ){の部分)。

一応可能性として、他の関数がこの関数近辺のメモリを壊しており、その壊れるアドレスがnum = 1;の有無によって変わってしまうので、ハングアップの有無と偶然一致してしまう…というのはありそうなのですが、しかしそれだと他の部分のソースをいじってもハングアップしそうですし…

とりあえずもう一度見直してみます。


tetrapod  2006-09-16 04:03:21  No: 63015

while (num==1) {/*numを変更するコードが無い*/}
なんてコードがあって Debug だと最適化がかからないからOK
Release だとコンパイラの最適化によって結果的にバグっているとか
if (num==1) { 無限ループ } else { なにもしない }


SPQR  2006-09-20 03:56:44  No: 63016

結局該当の関数の辺りをいくら調べても原因は不明だったのですが、その後全く別の部分に大量にソースを追加したところ、なぜかハングアップしなくなりました。正確にはnumが不定のため、文字の色が赤と白でコロコロ変わる正しい?動作になりました。

ということで、やはり皆さんのおっしゃる通り別の部分がハングアップの原因だったようです。XDBitがうんぬんというのは全く私の勘違いでした。申し訳ありませんm(__)m

ちなみにwhile (num==1) {のようなコードはありませんので原因はそれではなかったのですが、マルチスレッドで開発しているため、numが少なくなるあたりで、どこかスレッドセーフになっていない部分があるのかも知れません。

どちらにせよ、お騒がせして申し訳ありませんでしたm(__)m


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加