コンパイラを使用して AIX でCppcheckを構築する作業を行っています (前の質問を参照)。チェッカー クラスはすべてクラスから派生し、そのコンストラクターは各オブジェクトをグローバル リストに登録します。xlCCheck
check.h
class Check {
public:
Check() {
instances().push_back(this);
instances().sort();
}
static std::list<Check *> &instances();
virtual std::string name() const = 0;
private:
bool operator<(const Check *other) const {
return (name() < other->name());
}
};
checkbufferoverrun.h
class CheckBufferOverrun: public Check {
public:
// ...
std::string name() const {
return "Bounds checking";
}
};
私が抱えていると思われる問題は、instances().sort()通話にあります。sort()は静的リスト内の各ポインターでCheck::operator<()which 呼び出しを呼び出しますが、リストに追加されたばかりのインスタンスはまだコンストラクターを完全に実行していません (まだ 内にあるため)。したがって、コンストラクターが完了する前にそのようなポインターを呼び出すと、未定義の動作になるはずです。Check::name()instances()CheckCheck::Check()->name()CheckBufferOverrun
これは本当に未定義の動作ですか、それともここで微妙な点が欠けていますか?
への呼び出しが厳密に必要だとは思わないことに注意してくださいsort()。ただし、その効果は、Cppcheck がすべてのチェッカーを決定論的な順序で実行することです。これは、エラーが検出された順序での出力にのみ影響します。これにより、特定の順序での出力が期待されているため、一部のテスト ケースが失敗する原因となります。
更新:上記の質問はまだ(ほとんど)残っています。ただし、コンストラクターでの呼び出しが問題を引き起こさなかった本当の理由sort()(つまり、純粋な仮想関数の呼び出しによるクラッシュ) は、Check::operator<(const Check *)実際にはsort()!によって呼び出されないためだと思います。むしろ、代わりにポインターsort()を比較するように見えます。これは と の両方で発生し、Cppcheck コード自体に問題があることを示しています。g++xlC