計算量の多い論理演算です
説明
この欠陥は、以下の条件がすべて当てはまる場合に発生します。
左辺オペランドと右辺オペランドに二次的影響がない。
右辺オペランドにメンバー関数
const
の呼び出しが含まれていない。左辺オペランドに 1 つ以上のメンバー関数
const
の呼び出しが含まれている。
オペランドの潜在的な二次的影響を評価する場合、以下のようになります。
Polyspace® はクラスのメンバー関数
const
に二次的影響がないと想定します。非メンバー関数には二次的影響があると想定されます。Polyspace は C++ 規格に従って浮動小数点演算を扱います。C++03 以前では、浮動小数点演算に二次的影響はありません。C++11 以降では、浮動小数点ステータス フラグを変更して異常な結果や補足情報を示すなど、浮動小数点演算が二次的影響を及ぼす可能性があります。浮動小数点環境を参照してください。
Polyspace は、
struct
またはクラスのbool
変換演算子と論理NOT
演算子を組み込み演算子として扱います。このような演算はメンバー関数呼び出しとして扱われません。標準テンプレート ライブラリには、このようなbool
変換演算子や論理NOT
演算子を定義する多数のクラスが含まれています。
リスク
論理演算を評価するときに、コンパイラは最初に左辺引数を評価し、必要な場合にのみ右辺引数を評価します。論理演算で、関数呼び出しを左辺引数として使用しながら、定数および変数を右辺引数として使用するのは非効率です。次のコードについて考えます。
if(Object.attribute()|| var1){ //... }
if
ステートメント内の論理式で、コンパイラは常に関数呼び出し Object.attribute()
を評価します。関数の評価は常に必要であるとは限りません。たとえば、var1
が true
に評価された場合、論理式は常に true に評価されます。var1
は右辺オペランドであり、左辺オペランドではないため、コンパイラは不必要な関数呼び出しの評価を行うことになり、非効率です。この非効率なコードは正しくコンパイルされて機能するため、この欠陥は検出されない可能性があります。修正方法
右辺オペランドよりも "先" に実行する必要がある演算を左辺オペランドが実行するのではない場合、この欠陥を修正するには、論理式でのオペランドの順序を逆にします。これは右辺オペランドを安全かつ正しく評価するためです。
この条件に当てはまらない場合、コードは、フラグが設定された論理式をコンパイラが評価するとおりの順序に依存します。ベスト プラクティスは、式の評価順に依存しないことです。評価順が影響しないようにコードをリファクタリングすることを検討してください。コードをリファクタリングするのが不可能な場合は、注釈またはレビュー情報を使用して欠陥を正当化します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
パフォーマンスの改善の程度は、使用しているコンパイラ、ライブラリ実装、環境によって異なる可能性があります。
例
結果情報
グループ: パフォーマンス |
言語: C++ |
既定値: オフ |
コマンド ライン構文: EXPENSIVE_LOGICAL_OPERATION |
影響度: Low |
バージョン履歴
R2021a で導入