みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

引数に"1"を設定したのに関数内の変数では"0"として扱われてしまう。

引数に"1"を設定したのに関数内の変数では"0"として扱われてしまう。

今自分が持っているICカードをH8マイコンで読み取り、そこから取れたユニーク番号をフラッシュロムに書き込むという下の関数プログラムをつくっています。


void card_data_proc(WORD data,BYTE group,WORD num,BYTE add)
{
BYTE *pData;

if(add == TRUE)
pSCard->cad[group].data[num] = data;
else
pSCard->cad[group].data[num] = 0x0000;


pData = (BYTE *)SRAM_CARD_BUF;

pData[sizeof(CARD_DB) - 1] = env_crc(pData,sizeof(CARD_DB) - 1);

//flash_fs_write((DWORD)FLASH_CARD_ADDR - (DWORD)FLASH_BASE,(BYTE *)pSCard,sizeof(CARD_DB));
flash_fs_write((DWORD)FLASH_CARD_ADDR,(BYTE *)pSCard,sizeof(CARD_DB));
}


困っているのが、この関数を

WORD data;
BYTE MenuCardGroup;
int cardindex;


card_data_proc(data,MenuCardGroup,cardindex,1);
このプログラムで呼び出した行く時の動作をデバッガでおってみたところ、引数に”1”を渡したはずのaddの変数がなぜか”0"になってしまっていて、card_data_proc関数のif文でTRUEの条件に行かないのです。



なぜこのようになるのか御存じの方いらっしゃいませんでしょうか?
このような現象に遭遇した場合はどのような点を確認していったらよいのでしょうか?

投稿日時 - 2010-04-01 11:20:50

QNo.5794421

すぐに回答ほしいです

質問者が選んだベストアンサー

#4です。
>あと、呼び出し側の関数プロトタイプの確認ですかね。まずは。
こちらが本題なのですが、確認されましたか?

投稿日時 - 2010-04-02 14:34:29

お礼

回答頂きありがとうございます。お返事大変遅くなり、大変申し訳ございません。

現在のプログラムを確認したところ、この
”void card_data_proc(WORD data,BYTE group,WORD num,BYTE add02);”

この関数のプロトタイプ宣言が、このソースファイルのヘッダーファイルで宣言しているのを忘れていることがわかりました。

ヘッダーにプロトタイプ宣言してみたところ、引数の値が予定通りの値で渡されるのを確認しました。


コンパイル時のエラーなのですが、ちょっと特定出来ていません。

投稿日時 - 2010-04-23 10:35:28

このQ&Aは役に立ちましたか?

4人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.8

みんな関数原型(プロトタイプ)のことを指摘しているわけですが、実際のところどうなのでしょうか?
あと、BYTEやWORDなどのユーザー定義型ばかりなので正確な振る舞いがコード片からだけでは読み取れません。これらの型の定義も補足してください。

投稿日時 - 2010-04-04 12:40:16

お礼

回答頂きありがとうございます。お返事大変遅くなり、大変申し訳ございません。

現在のプログラムを確認したところ、この
”void card_data_proc(WORD data,BYTE group,WORD num,BYTE add02);”

この関数のプロトタイプ宣言が、このソースファイルのヘッダーファイルで宣言しているのを忘れていることがわかりました。

ヘッダーにプロトタイプ宣言してみたところ、引数の値が予定通りの値で渡されるのを確認しました。


コンパイル時のエラーなのですが、ちょっと特定出来ていません。

投稿日時 - 2010-04-23 10:36:47

ANo.7

#5です。

プロトタイプ void card_data_proc(WORD data,BYTE group,WORD num,BYTE add)

引数
WORD data;
BYTE MenuCardGroup;
int cardindex;
card_data_proc(data,MenuCardGroup,cardindex,1);
なので
cardindexの型がプロトタイプと一致していないですね。
この辺が原因かもしれません。
cardindexの代わりに直接数値(0とか1)を指定したらどうなりますか。

関数の記述より先にプロトタイプ宣言はしているのですよね。
コンパイル時にワーニングはでていませんか。

投稿日時 - 2010-04-04 08:09:08

お礼

回答頂きありがとうございます。お返事大変遅くなり、大変申し訳ございません。

現在のプログラムを確認したところ、この
”void card_data_proc(WORD data,BYTE group,WORD num,BYTE add02);”

この関数のプロトタイプ宣言が、このソースファイルのヘッダーファイルで宣言しているのを忘れていることがわかりました。

ヘッダーにプロトタイプ宣言してみたところ、引数の値が予定通りの値で渡されるのを確認しました。


コンパイル時のエラーなのですが、ちょっと特定出来ていません。

投稿日時 - 2010-04-23 10:36:05

ANo.5

TRUEの値が1とは限りません。(-1かもしれないし、0かもしれない)

if(add == TRUE) とするのであれば
card_data_proc(data,MenuCardGroup,cardindex,1);は
card_data_proc(data,MenuCardGroup,cardindex,TRUE);とすべきです。

デバッガで1に見えないというのはデバッガの都合で起きる事があります。
変数がレジスタに割り当てられている時には必要な時にならなければ正しい値がセットされないことがあります。
その間は別の変数のために使用されていたりします。

投稿日時 - 2010-04-01 12:29:53

お礼

回答頂きありがとうございました。

>card_data_proc(data,MenuCardGroup,cardindex,TRUE);とすべきです。

このやり方をやってみましたが、やはり現象は変わりませんでした。

一応この”TRUE”を検索してみたところ、
”#defineTRUE1”

という風に宣言されていました。


また、デバッガでのステップ実行ではなく、printf文を入れて、

if(add == TRUE){
printf("0402 TRUE\n\r");
pSCard->cad[group].data[num] = data;
}
else{
printf("0402 FALSE\n\r");
pSCard->cad[group].data[num] = 0x0000;
}

というように設定してみたのですが、
"printf("0402 FALSE\n\r");"このprintfを必ず通過してしまいます。

投稿日時 - 2010-04-02 13:58:14

ANo.4

とりあえず、
if(add == TRUE)
ここは
if( add )
のほうがよいでしょう。
あと、呼び出し側の関数プロトタイプの確認ですかね。まずは。

投稿日時 - 2010-04-01 11:48:11

お礼

回答頂きありがとうございました。

この”if( add )”というのをやってみたのですが、やはり結果は変わりませんでした。

投稿日時 - 2010-04-02 13:48:34

ANo.3

#1さんの回答を見て、自分の書き方がやや不親切だったことに気付いたので補足しておきます。

> 呼び出し元のコードや

正しい関数原型がある状態で呼び出したのか、関数原型なしで呼び出したのか、間違った関数原型で呼び出したのかによって状況が変わります。
正しい関数原型がある状態で呼び出したのであれば、実引数と仮引数の型が異なることは問題ではありません。

投稿日時 - 2010-04-01 11:43:48

ANo.2

> なぜこのようになるのか御存じの方いらっしゃいませんでしょうか?

呼び出し元のコードやコンパイルオプションなど、正確な情報がないのではっきりしたことはいえませんが...

addは4つめの引数ですので、レジスタではなくスタックに積まれるはずです。デバッガによっては、正確に値をウォッチできない場合がありますので、それで一見間違った振る舞いをしているように見えるということはありませんか?

if文のコードは、おそらくFALSEの条件でdataに相当するレジスタに0をセットし、pSCard->cad[group].data[num]に代入するように展開されると思いますので、ステップ実行するとTRUE側でなくFALSE側が実行されているように見える場合があります。

> このような現象に遭遇した場合はどのような点を確認していったらよいのでしょうか?

逆アセンブルしながら、実際はどうなのかを追跡してください。

投稿日時 - 2010-04-01 11:38:52

お礼

回答頂きありがとうございました。

>逆アセンブルしながら、実際はどうなのかを追跡してください。

うーん、大変そうな作業ですねぇ

投稿日時 - 2010-04-02 13:07:08

ANo.1

呼び出された方では
void card_data_proc(WORD data,BYTE group,WORD num,BYTE add)
呼び出す方では
WORD data;
BYTE MenuCardGroup;
int cardindex;
card_data_proc(data,MenuCardGroup,cardindex,1);
というように変数の型が一致していませんね。まずはそこから

投稿日時 - 2010-04-01 11:32:37

お礼

回答頂きありがとうございます。

一応、”int cardindex;”という変数の型と

void card_data_proc(WORD data,BYTE group,WORD num,BYTE add)
この関数の”WORD num”の変数型があっていなかったので、”WORD cardindex;”というように
変数型を合わせてみました。

これで、テストしてみたんですけど、

if(add == TRUE)
     pSCard->cad[group].data[num] = data;
else
pSCard->cad[group].data[num] = 0x0000;

このif文の分岐では必ずelse側に行ってしまいます。

投稿日時 - 2010-04-02 12:00:46

あなたにオススメの質問