質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%

Q&A

解決済

2回答

1682閲覧

PICマイコン ワーニング

raspypy

総合スコア247

0グッド

0クリップ

投稿2019/08/27 02:31

編集2019/08/27 07:52

##分からなこと
PICマイコンであるプログラムを作成していますが、
そのプログラムをビルドした際にでる「ワーニング」の原因と解決策が分からず、困っています。

##ワーニング
・変数i, x, dtについて、
ワーニング: (346) declaration of "x" hides outer declaration
・XBee_MakePacket10()関数内の計算式において、
ワーニング: (373) implicit signed to unsigned conversion

##プログラムコード

html

1int i , x ; 2char dt[36] ; 3char adrs[] = {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF} ; // 相手XBeeのアドレス 4 5void main(void) { 6 OSCCON=0x72; //PLL Disable/8MHz 7 ANSELA=0x04; //RA2 Analog Setting 8 ANSELC=0x00; //PORTC Digital Setting 9 TRISA=0x04; //RA2 Input 10 TRISC=0x28; //RC5, RC3 Input 11 LATC=0x00; 12 13 RXDTSEL = 0; 14 TXCKSEL = 0; 15 TXSTA = 0x24; //非同期/8ビット/パリティなし 16 RCSTA = 0x90; //シリアルポート使用/連続受信あり 17 BAUDCON = 0x00; // 8bit mode 18 SPBRGH = 0x00; //上位8bit 19 SPBRGL = 0x33; //下位8bit 20 21 while(1){ 22 i = XBee_MakePacket10(dt,adrs,"test",4) ; 23 x = XBee_SendPacket10(dt,i,0) ; 24 __delay_ms(5000); 25 } 26} 27 28 29void UART_Send(const char *dt,int num) 30{ 31 int a ; 32 for (a = 0 ; a < num ; a++) { 33 while(TXIF == 0) ; // 送信可能になるまで待つ 34 TXREG = *dt++ ; // 送信する 35 } 36} 37 38 39char XBee_CheckSum_Make(char *packet_dt,int len) 40{ 41 int i , c , x ; 42 43 c = len - 4 ; 44 x = 0 ; 45 packet_dt = packet_dt + 3 ; // 4バイト目から開始 46 for (i = 0 ; i < c ; i++) { 47 x = x + *packet_dt ; 48 packet_dt++ ; 49 } 50 x = 0xff - (x & 0xff) ; 51 return (unsigned int) x ; // 計算したチェックサム値を返す 52} 53 54 55int XBee_MakePacket10(char *packet_dt, const char *adrs, const char *data, int num) 56{ 57 int x , i ; 58 59 packet_dt[0] = 0x7E ; // 開始コード 60 x = num + 14 ; 61 packet_dt[1] = (unsigned int)(x / 256) ; // フレームデータの長さ 62 packet_dt[2] = (unsigned int)(x % 256) ; 63 packet_dt[3] = 0x10 ; // フレームタイプ 64 packet_dt[4] = 0x00 ; // フレームID 65 for (i = 5 ; i < 13 ; i++) { 66 packet_dt[i] = *adrs ; // 送信先の64ビットアドレス 67 adrs++ ; 68 } 69 packet_dt[13] = 0xFF ; // 送信先の16ビットアドレス 70 packet_dt[14] = 0xFE ; 71 packet_dt[15] = 0x00 ; // 最大ホップ数 72 packet_dt[16] = 0x00 ; // 送信オプション 73 for (i = 0 ; i < num ; i++) { 74 packet_dt[17+i] = *data ; // 送信するデータ 75 data++ ; 76 } 77 i = 17 + num ; 78 x = i + 1 ; 79 packet_dt[i] =XBee_CheckSum_Make(packet_dt,x) ; // チェックサム 80 81 return x ; // 作成したパケットの長さを返す 82} 83 84 85int XBee_SendPacket10(char *packet_dt,int len,int sw) 86{ 87 if (sw == 0) { 88 UART_Send(packet_dt,len) ; 89 } 90}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

2つ目のワーニングは、整数演算において、符号付きと符号なしの変換が起きたときに生成されます

ワーニングは、エラーではないけどバグの可能性が疑われる記述だ、ということで生成されるんで、たいていの場合は大きなお世話でしかないですが、これのおかげでちょっとした記述ミスを見つけられたりするので、あんまし見逃すのももったいない話ですね

投稿2019/08/27 04:31

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raspypy

2019/08/27 05:56

ありがとうございます。 2つ目のワーニングは、(unsigned int)を付け加えることで、解決できました。 >記述ミスを見つけられたりするので、あんまし見逃すのももったいない話ですね おっしゃるとおり、ミスが見つかるときもあるので、なるべくワーニングは出さないようにしたいと思っています。 変数i, x, dtについてのワーニングについても考えてみます。
y_waiwai

2019/08/27 06:20

そのコンパイラのcharはデフォルトでunsigned char じゃないですか? コンパイラのマニュアルを確認してみては。 1つ目のワーニングはグローバル変数の方を名前変更してみては。 あるいはみなローカル変数にしてしまうとか
raspypy

2019/08/27 07:47

いつも回答ありがとうございます。 ご指摘の通り、1つ目のワーニングはグローバル変数の方を名前を変更したら解決できました。 2つ教えていただけると助かります。 ①次のご指摘は、今回のワーニングの件と何か関係がありますでしょうか。 >そのコンパイラのcharはデフォルトでunsigned char じゃないですか? ②タイマ割込みの設定のときにもワーニングが1か所ありました。 対象のコードは、TMR1L = (63036 & 0x00ff); 発生しているワーニングは、warning: (751) arithmetic overflow in constant expression となっていますが、こちらに関してもワーニングの原因を教えていただけると助かります。
y_waiwai

2019/08/27 07:56

2つ目のワーニングは符号なし←→符号付きのキャストが起こったことを通知しています 該当行でそのワーニングが出たということは、charが、unsigned ではないか、と思っただけです 組み込み向けのコンパイラでは、往々にしてcharのデフォルトが符号なしの場合があります > warning: (751) arithmetic overflow in constant expression 定数がオーバーフローしている、という警告です 63036 というのは、2バイトintで表現できない数値(オーバーフローしている)のためでしょうね。 おそらく、63036l とlongであることを明示しとけばそれは出なくなるでしょう
raspypy

2019/08/27 08:04

charの件、説明ありがとうございました。 warning: (751)の件についても、説明ありがとうございます。 TMR1L = (63036l & 0x00ff); と、long型であることを明示してビルドしてみましたが、同じワーニングが発生してしまいます。 度々すみませんが、コメントいただけると助かります。
y_waiwai

2019/08/27 08:19

んじゃ、63036u にしてみては
raspypy

2019/08/28 00:51

度々すみません。 63036uでも試してみましたが、同じワーニングが発生してしまいます。
raspypy

2019/08/28 01:16

割込みの設定は、次の通りです。 TMR1H = (63036 >> 8); //タイマー1の初期化(65536-2500=63036); 63036 (0xF63C)を右に8bitシフトするので、上位8bit 0xF6をTMR1Hへ代入 TMR1L = (63036 & 0x00ff); 63036 (0xF63C)と0x00ffとの論理積をとるので、下位8bit 0x3CをTMR1Lへ代入 このため、 TMR1L = (unsigned char) (63036 & 0x00ff); としてみましたが、同じワーニングが発生してしまいます。
y_waiwai

2019/08/28 01:39

なら、 TMR1L = 0x3c; としてみたらワーニングなくなりますか? なんか他の場所のワーニングじゃないかという気がしますが
raspypy

2019/08/28 01:43

TMR1L = 0x3c; としたら、ワーニングがなくなりました。 このワーニングの解決方法としては、2バイト(8bit)の値に自分で変換してから代入するしか方法がないのでしょうか。
y_waiwai

2019/08/28 01:52

うーん、示したようにlongと明示したら出なくなるはずですが、それがそのコンパイラの仕様なんでしょうね TMR1L = ((long)63036 & 0x00ff); TMR1L = ((int)63036 & 0x00ff); とかいろいろやってみれば。
raspypy

2019/08/28 02:24

TMR1L = (unsigned long)(63036u & 0x00ff); とすると、ワーニングが消えました。 TMR1L = (unsigned int)(63036 & 0x00ff); TMR1L = ((unsigned int)63036 & 0x00ff); とすると、ワーニングがでてしまいます。 初歩的なことを教えてください。 今使用しているマイコンは8bitマイコンですので、TMR1Lレジスタには8bitデータが格納されます。 しかし、タイマの設定値として4バイト(63036)の値を設定しなければならないため、 63036がunsigned long型であることを明示するために「63036u」とするところまでは、理解できました。 しかし、なぜ、次のように計算結果も(unsigned long)と明示しなければ、ワーニングが消えないのでしょうか。TMR1Lは8ビットのレジスタなのに、右辺にunsigned longと記述するのがなんか変に思い、質問させていただきました。(コンパイラがそうなっているから仕方ないのかもしれませんが、、、) TMR1L = (unsigned long)(63036u & 0x00ff);
y_waiwai

2019/08/28 02:33 編集

そのコンパイラでintとlongは何ビットの変数なんでしょう。 ふつう、8ビットCPUではint:16 long:32 ですが(ここらへんはコンパイラにより変わる)なんかここらへんでおかしな感じがしますが。 ちとその挙動は私自身納得行かないところではありますが。。 TMR1L = (63036ul & 0x00ff); ではどうなります?
raspypy

2019/08/28 03:15

昨日、ご指摘していただいたあと、私も TMR1L = (63036ul & 0x00ff);  この記述ならワーニングが消えるはず…と思って試しましたが、ダメでした。 使用しているコンパイラは、XC8ですが、 int 16ビット、long 32ビットの変数となるはずです。
y_waiwai

2019/08/28 03:18

うーん、、納得いかんなー(再 このコンパイラはこういうもん、とおもっとくしかないでしょうね。
raspypy

2019/08/28 03:33

>このコンパイラはこういうもん、とおもっとくしかないでしょうね。 挙動が納得できておりませんが、私もそう思うようにしました。 色々とコメントありがとうございました。
guest

0

一つ目のワーニング 

「ワーニング: (346) declaration of "x" hides outer declaration」

は、プログラムの1行目で、xをグローバル変数として宣言しているのに、int XBee_MakePacket10(char *packet_dt, const char *adrs, const char *data, int num) のプログラムの中(1行目の" int x , i ;")でxをローカル変数として宣言しているしているから、
『XBee_MakePacket10 の中でxを宣言しているので、外側で宣言されている(グローバルの)xが隠されてしまいますよ(この関数の中でxというとローカルのxの事で、グローバルのxにはアクセスできないですよ』という注意が為されているのです。

==
二つ目のワーニングは、プログラムのどこで発生するのですか??

投稿2019/08/27 02:54

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raspypy

2019/08/27 03:02

回答ありがとうございます。 iとxについてのワーニングについて理解できました。 この場合、無視しても良いのでしょうか。 ワーニングを解決する方法がありましたら、教えていただけると助かります。 2つ目のワーニングについては、XBee_MakePacket10()関数内の次の計算式の部分で発生しています。 packet_dt[1] = x / 256 ; // フレームデータの長さ packet_dt[2] = x % 256 ;
coco_bauer

2019/08/27 05:52

グローバル変数として定義されているxは、main関数の中で代入されるだけで、その値が使われていません。main関数でxに値を代入しているのは何故なのでしょうか? XBee_SendPacket10関数の中で、ans変数は0が代入されるだけですから、return ans; で常に0が返されますが、意味がありますか? このような視点に立って、プログラムを見直してみることをお勧めします。 ワーニングは有益な助言で有る場合が多いですから、無視すべきではありません。ワーニングの無視は、バグ(プログラムのミス)を取り損ねる原因になりますからね。
raspypy

2019/08/27 05:56

2つ目のワーニングは、(unsigned int)を付け加えることで、解決できました。
raspypy

2019/08/27 07:45 編集

1つ目のワーニングは、グローバル変数の方を名前を変更したら解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問