のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

SH SQMlintのMISRA-C(1998)の結果

MISRA-C 1998について出力された一覧例です。

番号2004 番号1998 種別 内容
1.1? 1 Complaining syntax error at : ,
typedefや配列の宣言の最後にカンマがある
6.3 13 Complaining typedef shall be used instead of the basic types
基本(char,int,short,long,float,double)型はサイズが変わる可能性があるので、サイズ(Byte,Int16,Int32)と符号がわかるような型として定義するべきである。
廃止? 18 Complaining numeric constant should be suffixed to indicate type
 
5.2 22 Complaining identifier (xxx) shall not hide identifiers in outer scope
      外部スコープの識別子が隠蔽されることになるため、内部スコープの識別子は外部スコープの識別子と同じ名前を用いてはならない。
5.4 29 Complaining a cast operation with an incompatible enum type
タグ名は固有の識別子でなければならない
12.4 33 Warning right operand of '&&' operator can make side effects
論理演算子&&又は||の右側オペランドは、副作用があってはならない。
     右側には関数を書かず、関数は一度何か変数に代入してから評価してください。
     &&や||の右側は、評価されない場合があります。 
12.5 34 Complaining left operand of '||' operator is not primary expression
  Complaining right operand of '||' operator is not primary expression
論理演算子&&または||のオペランドは、一次式ででなければならない。
&&や||の両側に括弧を入れればいいと思います。
12.6 36 Complaining operator '&' can be confused with operator '&&'
論理演算子(&&||!)のオペランドは、実質的なブール型になるべきである。実質的なブール型である式は、(&&||!)以外の演算子オペランドとして用いるべきでない。
if((あああ&0x01)!=0)とかにすればいいのかな?
&と&&の間違えがないか確認するルールです。
12.7 37 Complaining bitwise operation shall not be performed on signed integer, left operand of '|' operator
ビット単位の演算子は、潜在型が符号付のオペランドに対し適用してはならない。
定数にunsignedを示すUをつける0xffU
10.5 37 ビット単位の演算子〜及び<<が、潜在型のunsigned char又は、unsigned shortであるオペランドに適用される場合、その結果は、そのオペランドの潜在方へ直ちにキャストさせる。
uint8 port = 0x5aのとき 〜portは0xffa5(16bitマシン)、0xffffffa5(32bitマシン)
一度キャストで制限してから処理すればいいのかな?
12.8 38 Complaining shift count out of left operand object size
シフト演算子の右側のオペランドの値は、0以上、かつ、左側のオペランドの潜在型のビット幅未満でなければならない。
こんな感じかな ((uint16)*(byteaddr))<<8 | *(byteaddr+1)
12.8 38 Complaining non-constant shift count
変数でシフトしているので、結果が削られないか確認が必要
10.1 43 Complaining information loss conversion (from 'signed int' to 'unsigned short') in assignment operation
次の条件に該当する場合、整数型の式の値を異なる潜在型に暗黙的に変換してはならない。
a)同じ符号属性をもつより大きな型への変換でない場合
b)式が複合式である場合
c)式が定数でなく、関数の実引数である場合
d)式が定数でなく、return式である場合
符号ありから 符号なしへ しかも 小さい型へ 代入してるのか
11.1 45 Complaining (unsigned char *) is a cast to a pointer
11.1 45 Complaining (unsigned char *) is a cast from a pointer
ポインタ型とをさらにキャストしている
文字列リテラルはchar *かな?、char *をunsigned char*に キャストするとなるのかな?
const unsigned char aaa[] = {'A','B','C','\0'};とかに変えれば動くのかな
10.4 48 Complaining operand of '*' operator should be cast to 'unsigned long' explicitly
予期する結果を生成するには混合算術精度は明白なキャストを使用すべきである。
XXX = (ulong)WWW * (ulong)ZZZ と書いたほうがいいみたい。
13.2 49 Complaining test of non-boolean value against 0 should be made explicit, right operand of '&&' operator
オペランドが実質的なブール型である場合を除き、0との比較テストは明示的に行うべきである。
if ((flg & 0x1)!=0)でいいのかな
14.5 57 Complaining 'continue' statement shall not be used
continue分を用いてはならない
基本はできるだけcontinue使わないほうがいいみたい。終了条件などループ周りの振る舞いを重点的にチェックすること。
読みにくくなるなら、残してもいいかなと思う
廃止? 58 Complaining 'break' statement shall not be used (expect in 'switch')
1998だと、Breakを用いてはならないだけど、2004ではループ内に終了用のbreakを1つ用いていいになってる。
読みにくくなるなら、残してもいいかなと思う
14.9 59 Complaining 'if' or 'switch' or loop body shall always be enclosed in braces
if, else if, else, while, do...while およびfor 文の本文を構成する文には必ず中カッコで括られていなければならない。
1行でも必ず括弧をつけてください。ifには必ずelseをつける。
14.10 60 Complaining 'if', 'else if' construct should contain final 'else'
ifには必ず{}をつける。elseも{}をつけること。
8.1 71 Complaining function prototypes shall be visible at the function definition (XXX)
プロトタイプ宣言がないので プロトタイプ宣言をすること。
16.4 74 Complaining parameter identifier (XXX) shall be identical for declaration/definition
宣言と定義が違っている。あわせること。
10.2 77 Complaining argument type shall be compatible with prototype, the XXXnd argument
関数に引き渡される引数の非修飾型は関数プロトタイプで定義された期待する非修飾型と互換性がなければならない。
14.7 82 Complaining function should have single point of exit
関数は1つの出口しか持ってはならない。
可読性と取引かな
16.9 85 Complaining identifier (XXXXX) is considered to be not function call but address
引数なしで呼び出された関数は空のカッコを持つべきである。
式中に関数名が含まれているとき、単項演算子&も、呼び出しのための( )演算子も無い場合に「違反」レベルでレポートします。&func にすればいいかな?
17.1 101 Complaining pointer arithmetic with '+' operator
ポインタ算術は、配列又は配列要素を扱うポインタだけに適用しなければならない。
*(p+5)=0は× 間接参照はすべて×
p[5]=0は○
17.3 103 Warning relational operation between pointers with '<' operator
2 つの被演算子が同じ型で、同じ配列や構造体、共用体を指し示す場合を除いては、関係演算子はポインタには適用してはならない。
p = array[size] if(p<=array[end])は○だが配列+1の要素に書き込んだりすると、動作未規定で×

実行時チェックが必要なもの(できるだけコードに埋め込む)

    1. 演算エラー
      1. オーバーフロー
      2. アンダーフロー
      3. 0除算
      4. シフトでのビット損失
      5. 式の評価でのエラー
    2. ポインタ算術
    3. 配列の境界エラー
    4. 関数の引数
    5. ポインタ間接参照

SQMlint
http://documentation.renesas.com/jpn/products/tool/rjj10j1600_sqmlnt_u.pdf

その他1
http://www.google.co.jp/url?sa=t&source=web&ct=res&cd=4&ved=0CBUQFjAD&url=http%3A%2F%2Fsec.ipa.go.jp%2Freports%2F20050523%2FCMGuide_V1-0.pdf&ei=GygpS6muBdegkQXTq8DwDA&usg=AFQjCNHfgn0FIsl3jCh6i4xPyXcm6KKEmQ&sig2=NLNdE3VeklKNeZaNuyamNw

その他2
http://www.cqpub.co.jp/dwm/Contents/0104/dwm010400331.pdf

参考文献(具体的な例が出ていていい。)

組込み開発者におくるMISRA‐C:2004―C言語利用の高信頼化ガイド

組込み開発者におくるMISRA‐C:2004―C言語利用の高信頼化ガイド