微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有效取消引用空指针的规则是什么?

如何解决有效取消引用空指针的规则是什么?

#include <iostream>

struct X
{
    bool isNull() { return this == nullptr; }
    bool isNullConst() const { return this == nullptr; }
};

bool isNull(X& x) { return &x == nullptr; }
bool isNullConst(const X& x) { return &x == nullptr; }

// always false or exception.
bool isNullcopy(X x) { return &x == nullptr; } 

int main()
{
    X* x = nullptr;
    std::cout << x->isNull() << '\n';
    std::cout << (*x).isNull() << '\n';
    std::cout << isNull(*x) << '\n';
    // std::cout << isNull2(*x) << '\n'; // exception.
}

在这里,我知道X::isNull()等效于isNull(X&)X::isNullConst()等效于isNullConst(const X&)

我不知道的是取消引用空指针是正常的。我认为对空指针的任何取消引用都会导致异常。

玩了一段时间的指针后,我得出结论,取消引用空指针本身不是问题,问题在于试图读取或写入空指针指向的地址。

并且由于这些函数位于内存中的众所周知位置,因此取消引用指向类的null指针并调用一个函数只会导致以null对象作为第一个参数的函数调用

对我来说这是新事物,但这可能不是完整的图片

起初我以为这是一个OOP概念,因此它应在Java中工作,但在这里不起作用并引起异常(这使我想到为什么它在Java中不起作用? ...):

class X
{
    boolean isNull() { return this == null; }
}

public class Main {

    public static void main(String[] args) {
        X x = null;
        System.out.println(x.isNull());
    }
}

因此,很明显,这与C ++有关,而不是总体上与OOP有关。

在所有情况下,取消引用空指针将是有效的,并且不会导致异常吗?

除了结构和类的指针是空指针,还有其他可以成功取消引用的东西吗?

还有,为什么在不访问其字段的情况下调用空指针函数会在其他语言(如Java)中引发异常?

在其中引用空指针有意义的一种情况是在Red-Black树中。空指针被认为是黑色的。

#define RED true
#define BLACK false;

struct Node
{
    bool color;
    
    bool isRed()
    {
        return this != nullptr && this->color == RED;
    }
};

bool isRed(Node* node)
{
    return node != nullptr && node->color == RED;
}

在这里,我认为将函数包含在Node类本身中是更有意义的,因为它与此相关。除了检查节点是否为空的所有逻辑以外,在其中包含与节点有关的所有逻辑并不是很方便。

解决方法

我认为对空指针的任何取消引用都会导致异常。

不。在C ++中,取消引用空指针的方法是undefinded behavior

C ++不是Java。 C ++确实有例外,但是它们仅用于特殊的casse,而不是在所有地方都使用(如Java)。您应该知道不允许取消引用空指针,并且编译器假定它永远不会在正确的代码中发生。如果仍然发生,则您的代码无效。

了解未定义的行为。当您想在C ++中做任何认真的事情时,一定要了解它。

有效取消引用空指针的规则是什么?

规则是:您不应这样做。执行此操作时,您的代码格式错误,无需进行诊断。这是另一种说法:您的代码具有未定义的行为。不要求编译器发出错误或警告,当您要求编译器编译错误的代码时,结果可能是任何事情。

,

在Java中,您的对象声明是引用。因此,您可以提供对方法的空引用,这不会造成伤害,因为该方法可以检查引用是否指向空对象。

但是在空引用上调用方法将不起作用,因为该方法是在引用后面的对象上调用的。由于为null,因此无法在任何对象上调用该方法,因此会引发NullpointerException。

,

在C ++中取消引用nullptr是未定义的行为,因此从技术上讲,当您尝试取消引用nullptr时,任何事情都可能发生(我的意思是: 任何事情 :))。

,

在C ++中有效取消引用空指针的规则是什么?

C ++标准实际上对于通过空指针进行间接调用本身是否有效没有特定的规定。没有明确禁止它。曾经使用“取消引用空指针”作为未定义行为的示例的标准,但是此示例已被删除。

有一个活跃的核心语言问题CWG-232,标题为“ “是否通过空指针进行的未定义行为导致间接访问?” 。它提议对措辞进行更改,以明确允许通过空指针进行间接访问,甚至允许使用该语言中的“空”引用。该问题创建于20年前,最近一次更新是在15年前,当时发现建议的措词不足。


以下是一些示例:

X* ptr = nullptr;

*ptr;

以上,间接结果被丢弃。在这种情况下,标准不能以某种方式明确说明其有效性。拟议的措词将明确允许这一点。这也是一个毫无意义的操作。

X& x = *ptr;
X* ptr2 = &x; // ptr2 == nullptr?

以上,通过null间接寻址的结果绑定到一个左值。现在,这显然是未定义的行为,但是建议的措辞可以允许这样做。

ptr->member_function();

上面,间接的结果通过左值到右值转换。无论函数做什么,它都有未定义的行为,并且在CWG-232的建议分辨率中将保持未定义。同样适用于您的所有示例。

其结果之一是return this == nullptr;可以优化为return false;,因为this在定义良好的程序中永远不能为空。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。