ループ内のコンテナに同じオブジェクトインスタンスを追加する自動コンパイラ検出
-
13-09-2019 - |
質問
これは愚かな間違いです:
List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
f.Fill(something.GetRecord());
fooList.Add(f);
}
もちろん、ループ内に新しいFooをインスタンス化する必要があります。
コンパイラはコンパイル時にこの種の間違いを検出できますか?
素朴な目には、この動作を検出できるように見えます(ループ内の同じオブジェクトのインスタンスでリストを記入してください)。次に、「コンテナを同じインスタンスで複数回埋めている」などの警告を発行する必要があります。
それで、私はどれほどナイーブですか?このようなものが存在する言語を知っていますか?
解決
はい、これは可能です。
ただし、ツールやコンパイラがこれについて警告するとは思わないので、独自の分析で拡張できるツールを使用する必要があります。 Javaのために、 FindBugs そのようなツールです。 C、C ++などの場合 GCC 4.5はプラグインを可能にします 人々が独自の拡張機能を書くために、そして クラング LLVMからもこれのために設計されています。もあります デヒドラ Mozillaから、再びC ++の場合。 MS言語には、があります フェニックスフレームワーク.
質問は、この分析をどのように書くのですか?それはもう少し注意が必要であり、ツールに依存します。しかし、基本的に:
- ループをかなり簡単に検出できます(「強く接続されたコンポーネント」を探してください)、
- エイリアス分析では、特定の変数またはパラメーターが1つのオブジェクトのみ、または多くのオブジェクトのみを参照しているかどうかを示します(おそらく「抽象オブジェクト」を探します)、
- オブジェクトまたは変数の静的タイプを使用して、適切なコンテナを見つけることができます。
そのため、通話を非常に簡単に検出できます List<>.append(x)
ループでは、xは1つのオブジェクトのみを参照できます。
他のヒント
オブジェクトの複数のインスタンスでリスト<>を入力する場合はどうなりますか?コードを飾る必要がありますか #pragma
それで、コンパイラはあなたを放っておきますか?
この種の制限があるようにクラスをどのように宣言しますか?リスト<>は本当にC#クラスに過ぎません。Mscorlib.dllを逆コンパイルして、その完全な実装を見ることができます。したがって、この種の知識を得るには、どこかでハードコード化されなければなりません。属性?それは非常に制限されるでしょう。コードを検証する特別な方法は?オブジェクトにオーバーヘッドを追加します。
この種のものは、理由で使用されることは決してありません(私は決して意味しません)。フレームワーク自体とコードのフレーズとパフォーマンスがヒットします(GCが行うにつれて、メモリの周りに移動する必要がある過剰なオブジェクトから)。