2009-06-11 9 views
2
Cで

++それはbiwiseのオペレータが意図された論理演算子を使用することが可能ですこれは不正な動作を引き起こします。maskedは0から255になるように意図されているときは0または1になります。そしてC++はそれまでに文句を言うことはありません。防止の誤用は

このようなエラーがコンパイラレベルで検出されるようにコードを設計することは可能ですか?

+1

ちょうど恥ずかしそうです:マスクされた値は、コンパイラに依存して0またはゼロ以外の値になります。 –

+1

@Martin York:ちょうどペタンティックになる:適合する実装でマスクされたものは0または1になります。 '&& 'の結果はC++の' bool'であり、整数型に昇格すると ' 「true」は「1」に変換される。 –

+0

古いものになっているはずです。私はCの日に戻って考えていたのですか? –

答えて

4

コードの任意の部分でビット単位の操作を直接使用することを禁止します。 には、代わりに関数を呼び出してください。

ので、代わりの:

int masked = unmasked & 0xFF; // izolate lowest 8 bits 

あなたが書く:ボーナスとして

int masked = GetLowestByte(unmasked); 

を、あなたは、エラーが発生しやすいビット演算の数十を敷き詰めていないコードベースを取得しますそれ。

実際にビット操作を行うのは1か所(GetLowestByteとその姉妹の実装)のみです。次に、あなたはそれを吹いたかどうかを確認するために、これらの行を2〜3回読むことができます。さらに、あなたはその部分を単体テストすることができます。

+3

私が書いている言語の正当な部分を私が使用することを許可しない場所で働きたくないです。 – shoosh

+0

@shoosh:(1)問題を解決するための戦略を掲示しました。 (2)私は禁止していない、私はちょうど特定の部分にこれらの操作を移動している(当然、それはクラスになります)。 –

+2

ビット単位の演算子が頻繁に使用され、論理演算子とともに使用されるコードでは、全体的な考え方がかなり妥当です。 – sharptooth

2

両方の演算子は整数に対して有効な演算を表しているため、問題を検出する方法はありません。コンパイラは、あなたが本当に望んでいる操作をどのように知っていると思いますか?

3

これはビットCaptain Obviousですが、もちろんencapsulationを適用してクラス内のビットマスクを非表示にすることもできます。次に、演算子のオーバーロードを使用して、ブール値operator&&()が適切であることを確認できます。

私は、このような「安全なマスク」の適切な実装は、パフォーマンス上非常に高価である必要はないと思います。

+0

私はそれをインライン化する最適化コンパイラに(質の高い)最適化のコストをかけます。 –

3

場合によっては、コンパイラの警告が表示されることがあります(私はあなたの例ではそうは思わないでしょう)。糸くずのようなツールは、間違いを見つけ出す可能性があります。

私は必ずする唯一の方法は、2つの演算子の間の差がより明確にするために、あなたのコーディング標準を定義することだと思う - のようなもの:

template<typename T> 
T BitwiseAnd(T value, T mask) { return value & mask; } 

をし、ビット演算子&と禁止|を