
|
 |
MAEC TOOL NEWS:
MAECT-M3T-NC308WA-021001D
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WA
ご使用上のお願い
|
Cコンパイラ(アセンブラ,統合化開発環境付き) M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WAの使用上の注意事項を連絡します。
- 自動変数の共用体に関する注意事項
- switch文に関する注意事項(1)
- switch文に関する注意事項(2)
- 同一変数を複数のif文で連続して参照する場合の注意事項
- 警告オプション -Wno_used_argument に関する注意事項
- #pragma JSRA, #pragma JSRW に関する注意事項
- 自動変数の共用体に関する注意事項
- 1.1 該当製品
- M32C/80, M16C/80, M16C/70シリーズ用 M3T-NC308WA V.5.00 Release 1
- 1.2 内容
- 自動変数として宣言された共用体のメンバへ値を代入し、その直後に同じ共用体の別のメンバを参照するソースプログラムをコンパイルすると、System Errorが発生する場合があります。
- 1.3 発生条件
- 以下の条件をすべて満たす場合に発生することがあります。
※ 条件を満たしていてもSystem Errorが発生しない場合があります。この場合は生成されたコードに問題はありません。
- (1) オプション -O, -O[1-5], -OR, -OS のいずれか1つ以上を選択している。
- (2) サイズが異なる複数のメンバを持つ共用体を自動変数として宣言している。
- (3) (2)の共用体のあるメンバ(メンバaとする)に、演算結果または変数の値を代入している。
- (4) (3)の代入の直後に、(2)の共用体のメンバa以外の1つのメンバ(メンバbとする)の値を参照している。
- (5)メンバaはメンバbよりもメモリ占有サイズが小さい型である。
- 1.4 発生例
-----------------------------------------------------------------------
union U { /* 発生条件(2) */
char a; /* 発生条件(5) メンバa:1バイト */
int b; /* 発生条件(5) メンバb:2バイト */
};
int func(char c)
{
union U u; /* 発生条件(2) */
u.a = c; /* 発生条件(3) メンバaに変数の値を代入 */
return u.b; /* 発生条件(4) メンバbの値を参照 */
}
-----------------------------------------------------------------------
- 1.5 回避策
- メンバaへの値の代入(発生条件(4))の直後にダミーのasm関数を挿入してください。
-----------------------------------------------------------------------
int func(char c)
{
union U u;
u.a = c;
asm(); /* ダミーのasm関数を挿入 */
return u.b;
}
-----------------------------------------------------------------------
- 1.6 恒久対策
- 本内容は、次期バージョンアップで改修する予定です。
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WA, ご使用上のお願い
MAECT-M3T-NC308WA-021001D
- switch文に関する注意事項(1)
- 2.1 該当製品
- M32C/80, M16C/80, M16C/70シリーズ用 M3T-NC308WA V.5.00 Release 1
- 2.2 内容
- switch文の制御式の型がchar, signed char, unsigned charのいずれかの場合、正しいcaseラベルに分岐しないコードを生成する場合があります。
- 2.3 発生条件
- 以下の条件をすべて満たす場合に発生します。
- (1) switch文の制御式の型が、char, signed char, unsigned char のいずれかである。
- (2) (1)のswitch文の中にcaseラベルが12個以上存在する。
- (3) コンパイルの結果、(1)のswitch文について、分岐先アドレスのテーブルとそのテーブルを用いた間接分岐のアセンブリ言語コードが生成されている。
- 2.4 発生例
[C言語ソース]
-----------------------------------------------------------------------
void func(char c)
{
switch (c) {
case 0:
...
-----------------------------------------------------------------------
[生成アセンブリ言語コード]
-----------------------------------------------------------------------
cmp.b #00H,R0L ; この場合R0Lと比較する即値定数が誤っている
jnc M2 ; ので、キャリーフラグが不正にONされて
mov.b #0dH,R0L ; defaultラベルへ分岐してしまいます。
M2:
indexwd.b R0L
S1:
jmpi.w L31 ; 間接分岐命令
L31:
.word L3-S1&0ffffH ; 分岐先アドレスのテーブル
.word L3-S1&0ffffH
.word L3-S1&0ffffH
...
-----------------------------------------------------------------------
- 2.5 回避策
- キャスト演算子を使ってswitch文の制御式をint型に変換してください。
[例]
-----------------------------------------------------------------------
int func(char c)
{
switch ((int)c) { /* int型へ変換 */
case 0:
...
-----------------------------------------------------------------------
- 2.6 恒久対策
- 本内容は、次期バージョンアップで改修する予定です。
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WA, ご使用上のお願い
MAECT-M3T-NC308WA-021001D
- switch文に関する注意事項(2)
- 3.1 該当製品
- M32C/80, M16C/80, M16C/70シリーズ用 M3T-NC308WA V.5.00 Release 1
- 3.2 内容
- switch文中で、同一の文に定数の値が連続している3つ以上のcaseラベルを付けている場合、正しいcaseラベルに分岐しないコードを生成する場合があります。
- 3.3 発生条件
- 以下の条件をすべて満たす場合に発生します。
- (1) オプション -O, -O[1-5], -OR, -OS のいずれか1つ以上を選択している。
- (2) switch文の中で、3つ以上のcaseラベルが同一の文に付けられている。
- (3) (2)caseラベルのうち3つ以上のcaseラベルの定数の値が連続している。
- (4) コンパイルの結果、switch文について、cmp命令とjeq命令の対が繰り返されているアセンブリ言語コードが生成されている。
- 3.4 発生例
-----------------------------------------------------------------------
int i, j;
void func(char c)
{
switch (c) {
case 0:
i = 0;
break;
case 1: /* 発生条件(3) 定数が
case 2: 1,2,3と連続しているcaseラベル
case 3: */
case 5:
i++; /* 発生条件(2) 上記3つのcaseラベルが付いた文 */
break;
case 4:
i = 1;
break;
}
j = i;
}
-----------------------------------------------------------------------
- ※ 上記では、switch文の条件式 "c" の値が1または2のとき、どのcaseラベルにも分岐せずにswitch文を終了してしまいます。
[生成アセンブリ言語コード]
-----------------------------------------------------------------------
.glb $func
$func:
cmp.b #00H,R0L
jeq L3 ; 正しいコードは以下
cmp.b #01H,R0L ; cmp.b #01H,R0L
jeq L15 ; jltu L15
cmp.b #03H,R0L ; cmp.b #03H,R0L
jeq L17 ; jleu L17
L15:
cmp.b #05H,R0L
jeq L17
cmp.b #04H,R0L
jeq L13
jmp L1
...
-----------------------------------------------------------------------
- 3.5 回避策
- 以下のいずれかの方法で回避してください。
(1) caseラベルの定数の値が3つ以上連続しないように並べ替える。
--------------------------------------------------------------------
case 1:
case 2:
case 5: /* case1,2,3の間にcase5を移動 */
case 3:
i++;
break;
--------------------------------------------------------------------
(2) caseラベルの定数の値が3つ以上連続しないようにダミーのasm関数を挿入する。
--------------------------------------------------------------------
case 1:
case 2: asm(); /* ダミーのasm関数を挿入(breakがないので、
以下の処理を続行します) */
case 3:
case 5:
i++;
break;
--------------------------------------------------------------------
- 3.6 恒久対策
- 本内容は、次期バージョンアップで改修する予定です。
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WA, ご使用上のお願い
MAECT-M3T-NC308WA-021001D
- 同一変数を複数のif文で連続して参照する場合の注意事項
- 4.1 該当製品
- M3T-NC308WA V.2.00 Release 1 ~ V.5.00 Release 1
- M3T-NC30WA V.3.20 Release 1 ~ V.5.00 Release 2
- M3T-NC79WA V.3.20 Release 1 ~ V.4.10 Release 1A
- M3T-NC77WA V.5.10 Release 1 ~ V.5.20 Release 4
- 4.2 内容
- 複数のif文条件式に同じ変数がある場合、コンパイル時にSystem Errorが発生する場合があります。
- 4.3 発生条件
- 以下の条件をすべて満たす場合に発生することがあります。
- (1) オプション -O, -O[1-5], -OR, -OS のいずれか1つ以上を選択している。
- (2) if-elseの形式のif文が、else側に2段以上ネストして存在する。ただし、最も内側はelseがないif文であっても発生する。
- (3) (2)のネストしているすべてのif文の条件式に同じ変数がある。
- (4) (2)のif-else文の後続処理に、(2)のif文と同じ変数を使うif文がある。
- (5) (4)のif文の実行直前に必ずしも(2)のif-else文を実行しない経路がある。
- (6) (4)のif文の直前の位置に、無条件分岐または関数からの復帰がある。
- 4.4 発生例
[例1]
-----------------------------------------------------------------------
int a, b, cond;
void func(void)
{
if (a == 1) { /* 発生条件(5) */
if (cond > 10) { /* 発生条件(2)(3)1段目のネスト */
b += 1;
} else if (cond > 5) { /* 発生条件(2)(3)2段目のネスト */
b += 2;
} else if (cond > 3) { /* 発生条件(2)(3)3段目のネスト */
return; /* 発生条件(6) */
}
}
if (cond == 1) { /* 発生条件(4) */
b += 3;
}
}
-----------------------------------------------------------------------
[例2]
-----------------------------------------------------------------------
int a, b, cond;
void func(void)
{
if (a == 1) { /* 発生条件(5) */
if (cond > 10) { /* 発生条件(2)(3)1段目のネスト */
b += 1;
} else {
if (cond > 5) { /* 発生条件(2)(3)2段目のネスト */
b += 2;
} else {
if (cond > 3) { /* 発生条件(2)(3)3段目のネスト */
b += 3;
}
}
}
} else {
if (a == 2) {
return; /* 発生条件(6) */
}
}
if (cond == 0x0001) { /* 発生条件(4) */
b += 3;
}
}
-----------------------------------------------------------------------
- 4.5 回避策
- 発生条件(4)の直前に、ダミーのasm関数を挿入してください。
[例1の回避例]
-----------------------------------------------------------------------
int a, b, cond;
void func(void)
{
if (a == 1) {
if (cond > 10) {
b += 1;
} else if (cond > 5) {
b += 2;
} else if (cond > 3) {
return;
}
}
asm(); /* ダミーの asm関数を挿入 */
if (cond == 1) {
b += 3;
}
}
-----------------------------------------------------------------------
- 4.6 恒久対策
- 本内容は、次期バージョンアップで改修する予定です。
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WA, ご使用上のお願い
MAECT-M3T-NC308WA-021001D
- 警告オプション -Wno_used_argument に関する注意事項
- 5.1 該当製品
- M32C/80, M16C/80, M16C/70シリーズ用 M3T-NC308WA V.5.00 Release 1
- M16C/60, M16C/30, M16C/20, M16C/10シリーズ用 M3T-NC30WA V.5.00 Release 2
- 5.2 内容
- 警告オプション -Wno_used_argument(-WNUA) を選択すると、引数のない関数に対して、誤った警告メッセージを出力します。
なお、メッセージが出力されても、生成されるコードは問題ありません。
- 5.3 発生条件
- 以下の条件をすべて満たす場合に発生します。
- (1) オプション -Wno_used_argument (-WNUA) を選択している。
- (2) 引数のない関数を定義(関数実体の記述)し、仮引数にvoidを記述している。
- 5.4 発生例
[C言語ソースa.c]
-----------------------------------------------------------------------
1 int f(void);
2 int i;
3
4 int f(void) /* 発生条件(2) */
5 {
6 i = 1;
7 return 0;
8 }
-----------------------------------------------------------------------
[出力メッセージ]
-----------------------------------------------------------------------
[Warning(ccom):a.c,line 8] function "f()" has no-used argument((null)).
===> }
-----------------------------------------------------------------------
※ メッセージ中の行番号は、関数定義の末尾行の行番号です。
- 5.5 回避策
- 生成されるコードは問題ありませんので、この警告は無視してください。
この警告は以下のいずれかの方法で抑止することができます。
- (1) -Wno_used_argument(-WNUA)オプションを指定しないでください。
※ ただしこの方法は、本来の警告 (引数を持つ関数を定義した場合に使われていない引数に対して出る警告) もされなくなりますので注意してください。
- (2) 関数の実体記述から仮引数の "void" を削除してください。
[例]
--------------------------------------------------------------------
int f(void); /* この関数を呼ぶときの引数のチェックに使用される
のでプロトタイプ宣言の仮引数は消さない */
int i;
int f( /* void */ ) /* 仮引数の void をコメントアウト */
{
i = 1;
return 0;
}
--------------------------------------------------------------------
- 5.6 恒久対策
- 本内容は、次期バージョンアップで改修する予定です。
M3T-NC308WA, M3T-NC30WA, M3T-NC79WA, M3T-NC77WA, ご使用上のお願い
MAECT-M3T-NC308WA-021001D
- #pragma JSRAまたは#pragma JSRWと#pragma PARAMETERの併用に関する注意事項
- 6.1 該当製品
- M32C/80, M16C/80, M16C/70シリーズ用 M3T-NC308WA V.5.00 Release 1
- M16C/60, M16C/30, M16C/20, M16C/10シリーズ用 M3T-NC30WA V.5.00 Release 1
- 6.2 内容
- #pragma JSRAと#pragma PARAMETER、または #pragma JSRWと#pragma PARAMETERを同一の関数に対して宣言すると、不要な警告メッセージが出力されます。なお、メッセージが出力されても、両方の#pragma指示とも正しく機能していますので、生成されたコードに問題はありません。
- 6.3 発生条件
- 以下の条件をすべて満たす場合に発生します。
- (1) ある関数を、#pragma JSRAまたは#pragma JSRWで宣言している。
- (2) (1)の関数を、さらに#pragma PARAMETERで宣言している。
- (3) (2)の宣言を(1)の宣言よりも後に記述している。
- 6.4 発生例
[C言語ソースjsra.c]
-----------------------------------------------------------------------
1 int func(int, int);
2 #pragma JSRA func /* 発生条件(1) */
3 #pragma PARAMETER func(R0,R1) /* 発生条件(2)(3) */
4
5 int main(void)
6 {
7 int i;
8 i = func(10, 20);
9 return i;
10 }
-----------------------------------------------------------------------
[出力される警告メッセージ]
-----------------------------------------------------------------------
[Warning(ccom):jsra.c,line 3] #pragma directive conflict
===> #pragma PARAMETER func(R0,R1)
-----------------------------------------------------------------------
- 6.5 回避策
- 生成されるコードは問題ありませんので、この警告は無視してください。
この警告を抑止する場合は、#pragma PARAMETER を #pragma JSRA または#pragma JSRW よりも前に記述してください。
[例]
-----------------------------------------------------------------------
1 int func(int, int);
2 #pragma PARAMETER func(R0,R1) /* #pragma JSRAの前に記述 */
3 #pragma JSRA func
-----------------------------------------------------------------------
- 6.6 恒久対策
- M3T-NC308WAは、次期バージョンアップで改修する予定です。
M3T-NC30WAは、V.5.00 Release 2 で改修済みです。
|