力允许取消零指针

Force allow dereference of NULL pointer

本文关键字:指针 取消 许取消      更新时间:2023-10-16

我有一个非常旧的(且巨大的)Win32项目,该项目通过施放指针将删除的指针指针使用Null指针进行大量检查。这样:

int* x = NULL; //somewhere
//... code
if (NULL == &(*(int*)x) //somewhere else
    return;

是,是的,我知道此代码很愚蠢,需要重构。但是由于大量代码,这是不可能的。目前,我需要在Xcode中的Macos Sierra下编译该项目,这导致了大问题……事实证明,在发布模式(使用代码优化)中,该条件以不正确的行为执行(由于删除了无效,因此称为未定义的行为指针)。

根据GCC的本文档,有一个选项 -fno-delete-null-null-pointer-checks ,但是当启用O1,O2或O3优化时,它似乎对LLVM不起作用。因此,问题是:我如何强制LLVM 8.0编译器允许这样的派遣?

更新。检查问题的真实工作示例。

//somewhere 1
class carr
{
public:
    carr(int length)
    {
        xarr = new void*[length];
        for (int i = 0; i < length; i++)
            xarr[i] = NULL;
    }
    //some other fields and methods
    void** xarr;
    int& operator[](int i)
    {
        return *(int*)xarr[i];
    }
};
//somewhere 2
carr m(5);
bool something(int i)
{
    int* el = &m[i];
    if (el == NULL)
        return FALSE; //executes in debug mode (no optimization)
    //other code
    return TRUE; //executes in release mode (optimization enabled)
}

-O0-O1上,something保留NULL检查,代码"工作":

something(int):                          # @something(int)
    pushq   %rax
    movl    %edi, %eax
    movl    $m, %edi
    movl    %eax, %esi
    callq   carr::operator[](int)
    movb    $1, %al
    popq    %rcx
    retq

但是在-O2及以上,进行了优化:

something(int):                          # @something(int)
    movb    $1, %al
    retq

在NULL上进行基于文本的搜索。然后在警告模式下运行编译器,然后打印出纸上的所有警告(如果您仍然有这样的技术)。现在,对于每个零,是有问题的零还是好的零?如果有问题,请将其重命名xnull。

现在,C 检查可能会在一个小型系统上失败,例如安装了640K,因为640K足以容纳任何人,但在您的现代系统上不足以使用许多GB。因此,一旦重新标记就将它们脱掉。如果不是这样。使Xnull在C 眼中具有有效地址的"虚拟对象"。

(从示例中,看来代码是LISP解释器。LISP同时需要一个空指针和虚拟指针,没有其他简单的写作方法)。