2011-06-15 3 views
4

以下のコードでMISRAがこのエラーを出すのを避けるにはどうすればよいですか?私は(unit16_t)でキャストしようとしました。しかし、それは明示的な変換を許可しませんでした。私のツールでMISRAエラーが発生したのはなぜですか?

複合式(MISRA C 2004規則10.1)における「unsigned int型」にMISRA型の基礎となる「unsigned char型」

 
uint8_t rate = 3U; 
uint8_t percentage = 130U;  
uint16_t basic_units = rate * percentage; 

答えて

4

問題はレートと割合の両方が静かに「INT」と入力し、整数プロモーションによって促進されるということです。したがって、乗算は符号付きの型で実行されます。

uint16_t basic_units = (uint8_t)(rate * percentage); 

EDIT:

MISRA互換コードは

uint16_t basic_units = (uint16_t)rate * (uint16_t)percentage; 

ようにコードを書き換えるか、MISRAが示唆するように実行するかのいずれかであり、すぐに「下地タイプ」への発現の結果を型キャスト:明確化が続く。

ISO 9899:1999 6.3.1.1 2

INTが元の型のすべての値を表すことができる場合、値はintに変換されます。 それ以外の場合は、符号なしのintに変換されます。これらは、整数 プロモーションと呼ばれます。 MISRA-Cから

参考テキスト:

MISRA-C:2004 6.10.3危険型変換:

/-/

- 算術における符合の変更オペレーション:インテグラルプロモーションは、多くの場合、タイプ(符号付き)の結果を返す2つの符号なしオペランドがになることがあります。例えば、が32ビットであるが、の場合が16ビットの場合、符号なしの16ビットの結果である場合、2つの16ビットの符号なしオペランドを加算すると符号付きの32ビットの結果が得られます。私は後者のみが基本となる型に即時キャストを強制するところ考え直しで、私は、10.5とMISRA 10.1を混同している可能性があり、実際に上記の私の第二ラインはMISRAを満たすかどうかどうかわからないんだけど、

特定のビット演算子の場合。

私はLDRA静的コード分析で両方の行をテストしましたが、不平を言っていませんでしたが、LDRAはMISRA-Cでも非常にうまく機能しません。

とにかく、元の質問に問題が速度及び百分率の両方暗黙INTはuint8_tのすべての値を表すことができるので、署名されINTを入力する整数キャンペーンによって変換されることです。だからそれはなる

uint16_t basic units = (int)rate * (int)percentage. 

これを防ぐには、明示的に型変換する必要があります。それ以上の考えを与えた後、私は上記の私の2つの1行目に行きます。

+0

2行目の 'uint16_t'に変換するのですか? – pmg

+0

2つの符号なし型 'uint8_t'の宣伝は、より大きな符号なし型' unsigned int'またはより単純に 'uint16_t'ではなく、符号付き型' int'をもたらすのはなぜですか? – Ioan

+0

@pmg私は実際にMISRAルール10.1と10.5を混ぜ合わせたと思う。それが〜または<<演算子であれば、私はMISRAが「基礎となるタイプ」に型キャストすることを余儀なくされたでしょう。私は事を明確にするために投稿を編集しました。 – Lundin

2

からの不正な暗黙的な変換暗黙的な変換を乗算するための乗算の前に行われます。乗算はあなたのツール

uint16_t basic_units = (unsigned)rate * (unsigned)percentage; 

結果unsigned値をシャット直前たぶん明示的な変換は、暗黙のうちに警告なしでuint16_tに変換する必要があります。あなたのツールは、あまりにもこのことについてPITAであることを選択した場合、別の明示的な変換を試してみてください。

uint16_t basic_units = (uint16_t)((unsigned)rate * (unsigned)percentage); 
+1

私はほぼ同じものを投稿しました。 MISRAはアドバイザリルールでunsigned(int)を使用すると戸惑うので注意してください。最大ツールシャットダウンのためにuint16_tに型キャストする必要があります。 – Lundin

+0

Hmm、私はMISRAのルールはありません:) 'uint16_t'が' int'よりも小さいランクのとき、問題は消えません。値はより大きな型の 'unsigned 「あまりにも。 – pmg

+0

実際、uint16_tがunsigned shortの場合は、引き続きプロモートされます。おそらく最高の(そしてほとんどのMISRAに準拠した)コードは、私の答えの2行目のコードのように、結果を型キャストすることになります。 – Lundin

1

MISRAルールは、計算に使用される「基底型」が結果の型と同じであることを保証しようとしています。それを実現するには、オペランドの一方、または両方、キャストすることができます:キャストせずに32ビットアーキテクチャで

uint8_t rate = 3U; 
uint8_t percentage = 130U;  
uint16_t basic_units = (uint16_t)rate * percentage; 

結果をOKである、しかし、次の点を考慮してください

uint32_t rate = ...; 
uint32_t percentage = ...; 
uint64_t basic_units = rate * percentage; 

32ビットアーキテクチャでは、対象の種類が64  ビットであっても、32  ビットで処理が実行されます。レートとパーセンテージが十分に大きい場合は、ビットで操作がラップされる可能性があるため、ターゲットタイプに適合するデータは失われます。

MISRAルールは、ターゲットプラットフォーム上のタイプのサイズに関係なく、コードをより安全にしようとしています。

関連する問題