是否发现C / C ++代码中的指针静态等效于HaltingΡroblem?

时间:2013-12-30 22:53:36

标签: c++ c pointers static-analysis halting-problem

我并非根深蒂固的静态代码分析,因此这个问题。

几年前,我读到使用静态代码分析区分代码与数据相当于Halting Problem。 (引用需要,但我不再拥有它了.Stackoverflow在这个herehere上有线程。)至少对于基于Von Neumann architecture的常见计算机体系结构,代码和数据共享相同的记忆似乎有意义。

现在我正在研究C / C ++代码和指针分析的静态分析;该程序不执行。不知怎的,我有一种感觉,静态跟踪指针值的所有创建和使用类似于停止问题,因为我无法确定内存中的给定值是否是指针值,即我无法通过指针值跟踪指针值的值记忆。 Alias analysis可能会缩小问题范围,但面对多线程代码似乎变得不那么有用了。

(有人甚至可能会考虑跟踪任意值,而不仅仅是指针:为任何给定的“有趣”值构建完整的值流似乎等同于停机问题。)

由于这只是一种预感,我的问题是:我可以参考更正式的发现吗?我错了吗?

4 个答案:

答案 0 :(得分:3)

您始终可以对此进行编码:

extern bool some_program_halts();
extern int* invalid_pointer();

#include <iostream>
int main()
{
    using namespace std;
    if( some_program_halts() ) { cout << *invalid_pointer() << endl; }
}

检查此程序是否取消引用无效指针等同于查明对some_program_halts()的调用是否停止。

答案 1 :(得分:1)

它几乎肯定是等价的,模数是C不是图灵等价语言的事实(给定的C实现是一个巨大的有限状态机而不是图灵机,因为表示类型 )。在有效类型为指针类型的对象中,指针不需要保留在原始表示中;您可以检查表示并对其执行任意操作,例如,加密指针并在以后解密它们。确定任意计算是否可逆,或者两个计算是否是彼此相反的,是(随意)可能等同于确定停止。

答案 2 :(得分:0)

如果我理解正确:是的,检查C或C ++程序是否访问无效指针等同于暂停问题(无论如何都是C或C ++程序)。

假设您有一个工具告诉您程序是否访问了无效指针,以及您想要检查暂停的程序。通过向每个指针添加额外信息,您可以检查(在运行时)指针是否有效;添加此类检查,失败时无限循环。您现在有一个没有无效指针访问的程序。通过替换程序可以使用无效指针访问终止的所有位置,当且仅当原始程序终止时,才会获得具有无效指针访问的程序。

答案 3 :(得分:0)

静态分析几乎总是近似值,通常可以通过减少the one in Alf's answer等程序的暂停问题来证明。但是,近似值可能会误报或误报。

  • “保守”静态检查只会包含误报。它永远不会接受“坏”程序,但它将不可避免地拒绝一些“足够复杂”的好程序。
  • “自由”静态检查会有误报。有时它会错误地接受错误的程序,但(通常)它也会接受所有好的程序。

一些例子:

  • Java的类型系统是保守的:类型为T的变量在运行时始终包含T类型的实例(或T或null的子类型),无论如何。
  • GCC选择警告未初始化的变量是自由的:它没有找到未初始化变量的所有潜在用途。 Here's an example of a false positive program.
  • 相比之下,Java对局部变量进行了保守的未初始化变量检查。如果它看到任何使用潜在未初始化变量的潜在执行路径,它就拒绝编译程序。

编制者经常使用自由支票来发出警告,并通过外部static analysis tools。类型系统和编译器优化之类的东西往往依赖于保守的检查是正确的。

许多任务都有几种不同精确度的合理保守和自由算法。别名分析is certainly one of these

有关更多信息,请参阅任何好的编译器教科书,例如the dragon book