メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: EXP46-C

boolean 形式のオペランドと一緒にビット演算子を使用しない

説明

ルール定義

boolean 形式のオペランドと一緒にビット演算子を使用しないようにします。1

Polyspace 実装

ルール チェッカーは、"ビット演算子と boolean 形式のオペランドの使用" をチェックします。

すべて展開する

問題

ビット演算子と boolean 形式のオペランドの使用は、次のようなビット演算子を使用したときに発生します。

  • ビット単位 AND (&&=)

  • ビット単位 OR (||=)

  • ビット単位 XOR (^^=)

  • ビット単位 NOT (~)

  • boolean 型の変数

  • 関係式または等式の出力

boolean 算術式とシフト演算で boolean 型の変数を配列インデックスとして使用してもこの欠陥は発生しません。

リスク

bool 型の変数や関係演算子の出力などの boolean 形式のオペランドは、通常、論理式で使用されます。boolean 変数や関係演算子を含む式でビット演算子を使用すると、論理エラーが発生する可能性があります。ビット演算子と論理演算子は似ているため、誤って論理演算子の代わりにビット演算子を使用することがあります。このような論理エラーは、コンパイル エラーにならないため、見つけにくいコード内のバグにつながる可能性があります。

修正方法

boolean 変数や関係演算子を含む式で論理演算子を使用します。このような式でビット演算子を使用する意図を示すには、小かっこを使用します。

例 — ビット演算子を使用したことで発生する可能性のあるバグ
class User{
	//...
	int uid;
	int euid;
public:
	int getuid();
	int geteuid();
};
void func ()
{
	User nU;
	if (nU.getuid () & nU.geteuid () == 0) {   //Noncompliant
		//...
	}else{
		//...
	}
}

この例では、if-else ブロックが条件付きで実行されます。条件ステートメントでは、論理 AND (&&) の代わりに、ビット単位 AND (&) が使用されていますが、間違っている可能性があります。関数 nU.geteuid() が 0 に評価され、nU.getuid() が 2 に評価される場合を考えてみます。このケースでは、& を使用すると、2&1false に評価されるため、コードの else ブロックが実行されます。逆に、&& を使用すると、2&&1true に評価されるため、コードの if ブロックが実行されます。&& の代わりに & を使用すると、見つけにくいコード内の論理エラーやバグにつながる可能性があります。Polyspace® は、関係演算子も使用されるこの種の式でのビット演算子の使用にフラグを設定します。

修正 — 論理演算子と boolean 形式のオペランドの使用

1 つの考えられる修正は、関係演算子や boolean 変数を含む式では論理演算子を使用することです。

class User{
	//...
	int uid;
	int euid;
public:
	int getuid();
	int geteuid();
};
void func ()
{
	User nU;
	if (nU.getuid () && nU.geteuid () == 0) {   //Compliant
		//...
	}else{
		//...
	}
}
修正 — オペランドをかっこで囲む

& 演算子を使用する場合、別の修正方法は、オペランドをかっこで囲むことにより、演算の順序と意図したロジックを維持することです。

class User{
	//...
	int uid;
	int euid;
public:
	int getuid();
	int geteuid();
};
void func ()
{
	User nU;
	if ((nU.getuid ()) & (nU.geteuid () == 0)) {   //Compliant
		//...
	}else{
		//...
	}
}

チェック情報

グループ: 02.式 (EXP)

バージョン履歴

R2019a で導入

すべて展開する


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.