为什么编译器无法在编译时检测到obj引用了类型B的对象,从而在我们尝试将其强制转换为类型A时报告错误?
public class A { }
public class B { }
static void Main(string[] args)
{
B b = new B();
object obj = (object)b;
A a = (A)obj; // exception
Run Code Online (Sandbox Code Playgroud)
感谢名单
Tom*_*cek 14
由于停止问题.这实际上意味着您无法确定程序将遵循哪条执行路径(并且有一个数学证明).例如,以下代码可能正确也可能不正确:
object o = SomeTest() ? (new A()) : (new B());
A a = (A)o;
Run Code Online (Sandbox Code Playgroud)
如果SomeTest方法总是返回true那么它是正确的.不幸的是,不可能做出决定.然而,该领域正在进行大量研究.尽管无法始终检查,但有些工具有时可以验证某些内容是否会成功,或者为您提供假设失败的执行路径示例.
这种技术的一个很好的例子是Code Contracts,它将成为Visual Studio 2010的一部分.我相信你可以使用它们来证明你的压缩是正确的.但是,没有明确的支持 - 尽管它会有用!
让我转过一个问题:如果编译器可以证明这一点,那么为什么我们需要演员表呢?演员的目的是告诉编译器"我比你更了解这个代码,并且我保证这个演员是有效的.我很确定这个事实,我愿意让你生成抛出异常的代码如果我错了." 编译器无法证明转换是否有效,因为转换是针对编译器无法证明其有效的情况.
编译器肯定可以实现在这样的微不足道的情况下工作的检查.但这样做不太可能帮助"真正的"代码,因为程序员很少编写这样明显错误的代码.
为了处理更复杂的情况,编译器必须执行更复杂的分析.这对于编译器编写者来说更难做,并且对于你的机器运行来说也更慢,并且它仍然无法捕获每个可能的坏演员.而且,由于大多数代码都没有这种容易识别的错误,因此不清楚收益是否值得编写分析的成本.
更复杂的静态分析的两个缺点是错误消息和误报.首先,使用工具解释代码中的问题通常比使工具仅检查问题要困难一个数量级.其次,当检查问题从"坏事X肯定会发生"转变为"可能发生的坏事"时,该工具更有可能在实践中标记那些不是问题的事情.
有一篇有趣的文章由一家公司撰写,销售静态分析工具,这些工具是从学术研究中分离出来的.他们发现的一件事是他们经常通过更复杂的分析减少销售量!几十亿行代码:使用静态分析查找现实世界中的错误
| 归档时间: |
|
| 查看次数: |
579 次 |
| 最近记录: |