自动编译器在循环中将相同对象实例添加到容器中的自动编译器检测
-
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, 查找bug 是这样的工具。对于C,C ++等 GCC 4.5将允许插件 让人们写自己的扩展名, 铛 LLVM也是为此设计的。也有 dehydra 来自Mozilla,再次用于C ++。对于MS语言,有 凤凰框架.
因此,问题是,您如何编写此分析?多数民众赞成在更棘手,并取决于该工具。但基本上:
- 您可以很容易地检测到循环(寻找“强烈连接的组件”),
- 别名分析可以告诉您特定变量或参数是指一个对象还是许多对象(也许是“抽象对象”),
- 您可以使用对象或变量的静态类型找到合适的容器。
因此,您可以很容易地检测到 List<>.append(x)
在一个循环中,x只能参考一个对象。
其他提示
如果您想用对象的多个实例填充列表<>怎么办?您需要用 #pragma
所以编译器让你一个人呆着吗?
您甚至如何宣布一堂课有类似的限制?列表<>实际上只不过是C#类,您可以对mscorlib.dll进行反复编译,并查看其完整实现。因此,要拥有这种知识,必须在某个地方进行硬编码。属性?那将是令人难以置信的限制。验证您的代码的特殊方法?会将开销添加到您的对象中。
这种东西从来没有(我确实是指)是出于某种原因的:它会有所帮助而不是妨碍它在实施困难中所需的真正成本的极少数情况(框架本身和您的代码)和性能命中(来自必须像GC一样在内存周围移动的过多对象)。
不隶属于 StackOverflow