4

私はこの機能を持っています:

void InitS(unsigned int &numS){
   // this function returns a container for unsigned int
   // but it has a cast for int
   numS = props.numOfS();
   if (numS > 0) {
        ..
   }
}

コンパイルされますが、次の MISRA 警告が表示されます。

MISRA-C++ ルール 4-10-2 (必須): リテラル ゼロ (0) は null-pointer-constant として使用してはならない。

さて、もしnumShots「本物の」ポインターだったら、私はに変更できたはず0ですNULL。しかしnumShots、参照であり、それはint.

MISRA は何を望み、その理由は何ですか?

4

3 に答える 3

4

numsは であるため、unsigned intと比較する必要があります0U。ここで、追加された 'U' は、リテラルが unsigned int であるのに対して、signed int なしであることを示します。

これは私のチームをいつも閉じ込めています。ゼロを符号なしとしてマークする必要がある理由がわかりません。

また、ポインタを扱っていません。関数シグネチャ はunsigned int&、変数がポインターではなく参照によって渡されることを示します。コピーではなく、元のオブジェクトを変更します。

于 2013-03-05T15:50:56.747 に答える
3

MISRA-C++ の経験はありませんが、MISRA-C の経験は豊富です。

MISRA-C には、MISRA-C++ にも適用される型安全性に関するいくつかの懸念があります。そのような懸念の 1 つは、暗黙的な型の昇格が発生しないようにすることです。これは妥当な懸念事項です。暗黙的な型の昇格は理解しにくく、バグにつながります。ほとんどの C および C++ プログラマーは、驚くべきことに、暗黙的な型昇格がどのように機能するかさえ知りません。これについてプログラマーを教育し、そのようなバグから保護するために、暗黙的な型変換/昇格に関する多数の MISRA ルールがあります。

  • そのようなルールの 1 つは、すべての整数リテラルに「u」サフィックスを強制します。ルールの背後にある理論的根拠は、最大の int 値に近い大きなリテラルが符号なしであることを明確にすることです。たとえば、リテラルの型は0x80000000読者には明らかではありません。(個人的には、このルールは不必要であり、多少見当違いであると考えています。暗黙の変換の危険性はすべて、他のルールによって既にカバーされているからです。)

  • NULL に対するポインタ チェックは明示的に行う必要があるという別のルールもあります。あなたは書くことを許されていません。if(ptr)むしろ書くべきif(ptr!=NULL)です。その根拠は、可読性と型の安全性です。

  • そして、ポインタをゼロリテラルと比較してはならないというルールがあるようです。この背後にある理論的根拠はわかりません。おそらく、ポインターと単純な整数変数を混同することを恐れているのでしょう。彼らは、C++ のヌル ポインターをわかりやすくするという Bjarne Stroustrup の野心から逸脱することを決定したようです。Stroustrup によると、C++ では NULL と 0 は常に同等です (ただし、C++11 にはこの混乱を完全に解決する nullptr キーワードがあります)。

上記のルールはどれも、あなたの例のコードとは何の関係もありません! 参照をゼロ リテラルと比較していますが、これは完全に安全です。MISRA チェッカーは 'u' 接尾辞の欠落について文句を言うかもしれませんが、あなたのチェッカーはそうではありませんでした。

私の結論は次のとおりです。

  • MISRA-C++ チェッカーに欠陥があり、誤ったエラーが発生します。
  • リテラル ゼロに対する特定の MISRA-C++ ルールには意味がないようです。このルールに対して MISRA 実装の逸脱を提起し、誰かがその根拠を提供できるまで、ルールを完全に無視する必要があります。
于 2013-03-06T14:23:32.493 に答える
0

私は間違っている可能性があります。私はプログラミングにあまり慣れていないため、おそらく答えは少し遅れていますが、MISRA-C チェッカーは「参照」型の変数をリテラル定数と比較しているので、参照には実際には有効ではありませんが、NULL 参照をチェックする必要があります」が、関数 props.numOfS() の戻り値を新しい変数に割り当ててから、numS で参照される変数への割り当てを試みることができます新しい変数で比較を行っている間に別の行。

すなわち

void InitS(unsigned int &numS){
   unsigned int foo;
   foo = props.numOfS(); //this function returns a container for unsigned int but it has a cast for int
   numS = foo;
   if (foo > 0) {
        ..
   }
}

その後、それが不平を言っているかどうかを確認してください。

于 2014-04-14T07:52:32.253 に答える