gpt4 book ai didi

c++ - 取消引用 typeid 中的空指针

转载 作者:IT老高 更新时间:2023-10-28 22:22:19 25 4
gpt4 key购买 nike

在研究最近的一个问题时,我发现了 '03 标准[1] 中的以下条款:

When typeid is applied to an lvalue expression whose type is a polymorphic class type (10.3), the result refers to a type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the lvalue refers. If the lvalue expression is obtained by applying the unary * operator to a pointer and the pointer is a null pointer value (4.10), the typeid expression throws the bad_typeid exception (18.5.3).

具体来说,我想知道最后一位,它为取消引用空指针的结果提供了明确定义的行为。据我所知,这是唯一一次这样做[2]。具体来说,dynamic_cast<T&>对于这种情况没有特殊处理,这似乎是一个更有用的场景。双重考虑dynamic_cast<T&>已经定义为在某些情况下抛出异常。

是否有特定原因对该特定表达进行特殊处理?这似乎完全是武断的,所以我猜他们想到了一些特定的用例。


[1] '11 中存在类似的子句,但它指的是左值表达式,而不是左值表达式。

[2] delete 0;dynamic_cast<T*>(0)接近了,但在这两种情况下,您都在处理指针值,而不是实际对象。

最佳答案

如果我更关注下一个子句 (5.2.8/3),我会看到这个

When typeid is applied to an expression other than an lvalue of a polymorphic class type, . . . The expression is not evaluated.

换句话说,与 sizeof(以及 C++11 中的其他内容)一样,编译器并不意味着实际运行您传递给 typeid 的代码,它只是应该分析它的行为。不幸的是,与 sizeof 不同,由于多态类型,结果有时取决于表达式的运行时行为。

Base* p1 = new Derived;
Base* p2 = new Base;
typeid(*p1); //equivalent to typeid(Derived) [assuming Base is polymorphic]
typeid(*p2); //equivalent to typeid(Base)

如果表达式完全未计算,则编译器无法检查 RTTI 以查看 p1 实际上指向 Derived 而不是 Base。然而,标准编写者决定更进一步,并声明如果表达式最终是指针类型的取消引用,编译器应该只对它进行部分评估。如果指针为空,则抛出 std::bad_typeid 而不是执行取消引用并引入未定义的行为。

将其与 dynamic_cast 进行对比。传递给 dynamic_cast 的表达式总是被完全评估,否则结果将毫无意义。由于无论如何都要求编译器对表达式进行全面评估,因此指示它提前停止并引发异常是没有意义的。

简而言之,这是给予特殊处理的方式与 sizeof(*(int*)0) 给予特殊处理的方式大致相同。 *(int*)0 并不意味着要被评估,因此没有理由首先引入未定义的行为,即使它看起来很糟糕。

关于c++ - 取消引用 typeid 中的空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6028427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com