ページ 11

ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 17:19
by NAN-A
お世話になっております。

現在VSC++2010、DXライブラリにてプログラムをしているのですが、
ブレイクをしたときのウォッチの値が正しい値を示さないことがあります。
具体的にはfor文のiの値がウォッチではずっと0のまま変化せず、
バグ探しに苦労をしています。
(iは正しく変化しているので、あくまでもウォッチでの表示がおかしいといった感じです)

ものすごく基本的なことのように感じますが、検索しても答えが見つからなかったので
ここで質問をさせて頂きます。
よろしくお願い致します。

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 17:51
by softya(ソフト屋)
リリースビルドの場合は正しい値は表示されません。
デバッグビルドで実行されていますか?

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 17:55
by NAN-A
softya(ソフト屋) さんが書きました:リリースビルドの場合は正しい値は表示されません。
デバッグビルドで実行されていますか?
デバッグビルドですね…

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 17:57
by softya(ソフト屋)
NAN-A さんが書きました:
softya(ソフト屋) さんが書きました:リリースビルドの場合は正しい値は表示されません。
デバッグビルドで実行されていますか?
デバッグビルドですね…
最適化オプションは、無効 (/Od)のままですか?

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 18:11
by non
関数の最初で宣言されているiとforループの中で宣言されているiが混在していませんか?

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 18:27
by NAN-A
>softyaさん
確認したところ無効のままでした…

>nonさん
iを使用する関数(というかfor文を使用する関数)では
先頭にstatic int i = 0 ;で定義しています。
もしかしてこれが何か問題がある…とかですかね?
以前はGlobalとExternでiを定義していたのですが、
あまりGlobalとExternは多用するなという記載があったので、
staticで毎回iを定義しています…

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 18:29
by beatle
for文に使う変数なんてstaticにする必要ないと思いますが.ただのローカル変数で十分では?
staticにする明確な理由があるのならば構いませんが.

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 18:34
by NAN-A
beatle さんが書きました:for文に使う変数なんてstaticにする必要ないと思いますが.ただのローカル変数で十分では?
staticにする明確な理由があるのならば構いませんが.
以前プログラムをしているときに、別の関数内に移動したときに、
前の関数で使用してたiを参照したりとめちゃくちゃなことをしていたので、
それを避けるため…というのもあります。(今なら普通に値を渡すようなプログラムをするとは思いますが…)

ただ、以前Globalにしていたときも同じような状況(ウォッチの値が正しくない)になったので、
それとは原因が異なるっぽいです…?

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 18:36
by softya(ソフト屋)
DXライブラリで書いているなら
for( int i=0 ; i<XXX ; i++ )
で構わないと思います。と言うかこれを試してみてください。
それと、やたらiが出てくるとプログラム中で意味がわからなくるので、iは避けて出来るだけ意味のある変数名を付ける癖はつけたほうが良いです。
適材適所なのでiが分かりやすい場合もあります。

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 18:54
by non
うまくいかないサンプルを作ってみました。

コード:

#include<stdio.h>

int main(void)
{
	int i;
	for(int i=0;i<3;i++){
		printf("%d ",i);
	}
	for(i=0;i<3;i++){
		printf("%d ",i);
	}

	return 0;
}

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 19:02
by NAN-A
>softyaさん
for文はいつもfor( i = 0 ; i<XXX ; i++ )ですね。
int iとするのは今はじめて知りました…それをやれば、static的な使い方になるのですかね?
やっぱりiをできるだけ使わない…に限るのですかね…for文なんぞ面倒くさいので、いつもiを使っておりました。

>nonさん
これは動作自体は正常に動くけど、ウォッチが上手くいかないというサンプルですよね?
下のfor文でブレイクすると、一つ前のiと関数の最初に定義したiを混在して、正しい値が表示されない…ということですかね。なるほど。

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 19:09
by softya(ソフト屋)
NAN-A さんが書きました:for文はいつもfor( i = 0 ; i<XXX ; i++ )ですね。
int iとするのは今はじめて知りました…それをやれば、static的な使い方になるのですかね?
やっぱりiをできるだけ使わない…に限るのですかね…for文なんぞ面倒くさいので、いつもiを使っておりました。
forの範囲が数行の単なる配列を連続アクセスするループならiで構わないと思います。それ以外の意味やループが長くなるならiはやめてください。
それとstaticなiは出てくる必然はありません。staticは次回の関数でも値を継続したい場合に使います。なのでforに使うのはふさわしく有りません。
for( int i=0 ; i<XXX ; i++ ) のiはforループ内だけ有効なiです。

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 19:14
by NAN-A
staticはその関数内だけで使用するための定義だと思っていました…もういちど勉強してきます。
そのばだけでつかいたいのであれば、for( int i=0 ; i<XXX ; i++ ) と書くわけですね…
ちなみにこのfor文で使用したiはfor文を抜けた後どうなるのでしょうか?
普通に開放されるということでしょうか?

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 19:19
by non
NAN-A さんが書きました:>nonさん
これは動作自体は正常に動くけど、ウォッチが上手くいかないというサンプルですよね?
下のfor文でブレイクすると、一つ前のiと関数の最初に定義したiを混在して、正しい値が表示されない…ということですかね。なるほど。
このようなプログラムではなかったのですか?
staticであるかないかは、関係ありません。

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 19:31
by NAN-A
non さんが書きました:
NAN-A さんが書きました:>nonさん
これは動作自体は正常に動くけど、ウォッチが上手くいかないというサンプルですよね?
下のfor文でブレイクすると、一つ前のiと関数の最初に定義したiを混在して、正しい値が表示されない…ということですかね。なるほど。
このようなプログラムではなかったのですか?
staticであるかないかは、関係ありません。
自分のプログラムでのfor文は全てfor( i = 0 ; i<XXX ; i++ )というものでしたので、
nonさんが提示していただいたようなプログラムではありませんでした。

なお、結局のところiをGlobalで定義して、staticを全部消したところ、ウォッチが正しく機能しました。
また、softyaさんの言うとおり今後はfor( int N ; N<XXX ; N++ )とfor文ごとにできるだけ、何かしらの変数を定義したいと思います。

一応状況は解決しましたので、解決とさせて頂きます。
色々とご意見いただき、ありがとうございました。

Re: ブレイクをしたときのウォッチの変数が正しい値を示さない

Posted: 2012年2月04日(土) 21:27
by softya(ソフト屋)
出来るだけ関数外の変数は減らして下さい。
変数のスコープと寿命を勉強されるべきだと思います。
「変数の記憶寿命とスコープ」
http://www2.ee.knct.ac.jp/el/E3/E305/lifeandscope.html

for( int N=0 ; N<XXX ; N++ )
も一つの方法ですが、

コード:

{
	int var;
	
}
などブロック内の寿命で参照有効な変数をできるだけ多用したほうが変な間違いが起きません。