診断ロジックは単純です。最初にポインタが参照解除された場合、nullptrと等しいかどうかが検証された場合に警告が発行されます。
もちろん、このようなパターンに合致したアナライザが静かになる状況は数多くあります。ポインターがnullptrと等しくない状況を含めると、アナライザーは静かになります。
ただし、Q_ASSERT(_parent)
は、ポインタ_parent
がゼロでないことを保証しません。 _parent
がゼロの場合、Q_ASSERTステートメントはqFatal関数を使用して次のメッセージを出力します。デフォルトのメッセージハンドラを使用している場合、この関数は中断してコアダンプを作成します。
独自のハンドラをインストールすることができます。ハンドラは、引き続きプログラムを実行します。理論的にはアナライザーは正しいです。 NULLポインタの潜在的な逆参照が発生する可能性があります。
私たちは理論家ではありませんが、実践的であり、このコードは正しいものとみなすべきです。このアナライザーは、マクロがまだ使用されているようなコードビューに精通していません。アナライザーを修正して、そのようなコードパターンを正しいものとして認識し始めます。私。ポインタ_parent
はnullptrと等しい場合
Q_ASSERT(_parent);
Q_ASSERT(row < _parent->childCount());
_parent->childCount()
関数呼び出し、実行されることはありません:。将来アナライザで、ここでは、と仮定しますポインタがNULLの場合、プログラムはqFatal()
を呼び出すため、以前の動作を停止します。
もちろん、上記のとおり、ハンドラの動作を変更することができ、プログラムを中止することはありません。しかし、実際には、誰もハンドラを変更し、ここで検討しているコードを書くことはありません。
これは答えの終点になる可能性があります。そこで、アナライザーを改良してみましょう。しかし、可能なすべてのオプションを予見することは不可能です。それが私たち自身のマクロならば、警告を抑制する方法は?
この自己生成エラーロギングシステムとアナライザーは、カスタム機能Foo()
について何も知らないとしましょう。
Q_ASSERT(row < _parent->childCount()) //-V595
別のオプションは、次のようにコードを書くのスタイルを変更して作成することです:
void Foo(bool expr);
#define Q_ASSERT(expr) Foo(expr);
inline T *sibling(int row) const
{
Q_ASSERT(_parent);
Q_ASSERT(row < _parent->childCount())
return _parent ? _parent->child(row) : nullptr;
}
最も簡単ではなく、最良の方法は、明示的なコメントを使用している偽の警告マークにある
inline T *sibling(int row) const
{
if (_parent == nullptr)
{
Q_ASSERT(false);
return nullptr;
}
Q_ASSERT(row < _parent->childCount());
return _parent->child(row);
}
このようなコードでは、理由がないため、アナライザは警告V595を発行しません。コードはもう少し長くなりましたが、私の意見では、これは論理的にはより正確で安全です。このような警告を扱うこの方法をお勧めします。
最後に、マクロで警告抑制メカニズムを使用します。この警告が表示されなくなります後
//-V:Q_ASSERT:595
:マクロが定義されているヘッダファイルでこれを行うには、コメントを記述する必要があります。もちろん、マクロが宣言されているファイルを変更することは必ずしも可能ではありません。次に、グローバルファイルのいずれかを使用できます。 Visual C++プロジェクトでは、stdafx.hが適しています。もう1つのオプションは、診断設定ファイル(pvsconfig)を使用することです。これらの方法はすべて、ドキュメント「Suppression of false alarms」に詳しく記載されています。 markup baseも存在します。
assert()で動作しますか? LLVMのスタティックアナライザもQ_ASSERTと混同しているのを覚えています。 –
assert()と同じです。 –
次の場合: 'return _parent!= nullptr? _parent-> child(row):nullptr; '? – AlexanderVX