编译器自动检测循环中向容器添加相同对象实例的情况

发布于 2024-08-05 02:37:50 字数 374 浏览 4 评论 0原文

这是一个愚蠢的错误:

List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
    f.Fill(something.GetRecord());
    fooList.Add(f);
}

当然,我应该在循环内实例化一个新的 Foo 。

编译器可以在编译时检测到这种错误吗?

对于天真的人来说,它看起来应该能够检测到这种行为(在循环中用同一对象的实例填充列表)。然后它应该发出警告,例如“您正在多次用同一实例填充容器。”。

那么,我到底有多天真呢?你知道有一种语言存在这样的东西吗?

This is a dumb mistake:

List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
    f.Fill(something.GetRecord());
    fooList.Add(f);
}

Of course, I should instantiate a new Foo inside the loop.

Can a compiler detect this kind of mistake at compile time?

To naïve eyes it looks like it should be able to detect this behavior (filling a List with instances of the same object in a loop). It should then issue a warning like "You are filling a container with the same instance more than once.".

So, how naïve am I being? Do you know of a language where something like this exists?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狼性发作 2024-08-12 02:37:50

是的,这是可能的。

但是,我认为工具或编译器本身不会对此发出警告,因此您必须使用可以通过您自己的分析进行扩展的工具。对于Java来说,FindBugs就是这样一个工具。对于 C、C++ 等,gcc 4.5 将允许插件供人们编写他们自己的扩展,以及来自 LLVM 的 clang 也是为此而设计的。还有来自 Mozilla 的 DeHydra,同样适用于 C++。对于 MS 语言,有 Phoenix 框架

那么问题来了,这个分析怎么写呢?这有点棘手,并且取决于工具。但基本上:

  • 您可以相当容易地检测循环(查找“强连接组件”),
  • 别名分析可以告诉您特定变量或参数是否仅引用一个对象或多个对象(也许查找“抽象对象”) ,
  • 您可以使用对象或变量的静态类型找到正确的容器。

因此,您可以很容易地检测到循环中对 List<>.append(x) 的调用,其中 x 只能引用一个对象。

Yes, this is possible.

However, I don't think a tool or compiler would warn about this themselves, so you'd have to use a tool which can be extended with your own analyses. For Java, FindBugs is such a tool. For C,C++, etc, gcc 4.5 will allow plugins for people to write their own extensions, and clang from LLVM is designed for this too. There is also Dehydra from Mozilla, again for C++. For MS languages, there is the Phoenix framework.

So the question is, how do you write this analysis? Thats a little more tricky, and depends on the tool. But basically:

  • you can detect loops fairly easily (look for "Strongly-connected components"),
  • alias analysis can tell you if a particular variable or parameter refers to just one object, or many objects (look for "abstract objects", perhaps),
  • you can find the right container using the static type of an object or variable.

So you could quite easily detect a call to List<>.append(x) in a loop, where x can refer to only one object.

唠甜嗑 2024-08-12 02:37:50

如果你想填充一个列表<>怎么办?一个对象的多个实例?您是否需要使用 #pragma 修饰您的代码,以便编译器不打扰您?

您如何声明一个类具有这些限制?列表>>实际上只不过是一个C#类,你可以反编译mscorlib.dll并查看其完整实现。因此,要拥有此类知识,就必须在某个地方进行硬编码。属性?这将受到极大的限制。验证代码的特殊方法?会增加你的对象的开销。

这种东西从来没有(我的意思是从来没有)使用过,这是有原因的:在极少数情况下,它会有所帮助而不是阻碍,远不超过它在实现难度(框架本身和代码)和性能影响(来自在 GC 执行其操作时必须在内存中移动的过度膨胀的对象)。

What if you want to fill a List<> with multiple instances of an object? Would you need to decorate your code with #pragma so the compiler leaves you alone?

How would you even declare a class to have these sorts of restrictions? List<> is really nothing more than a C# class, you can decompile mscorlib.dll and see its full implementation. So to have this sort of knowledge, it would have to be hard coded somewhere. Attributes? That would be incredibly restricting. Special methods to validate your code? Would add overhead to your objects.

This kind of stuff is never (and I do mean never) used for a reason: the extremely small number of cases where it would help rather than hinder comes nowhere near to outweighing the very real cost it would require in both implementation difficulty (of the framework itself AND of your code) and performance hits (from overbloated objects that have to be moved around the memory as the GC does its thing).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文