具有typeid调用的UB
UB with typeid invocation
我已经为理解typeid
运算符编写了代码。
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct C;
struct B
{
long unsigned int hash;
B(C *c);
};
struct C : B
{
C() : B(this)
{
cout << "C()" << endl;
}
};
B::B(C *c)
{
hash = typeid(*c).hash_code(); //1, UB?
}
C c;
int main()
{
cout << c.hash << endl;
cout << typeid(c).hash_code() << endl;
}
我认为我编写的代码在//1
产生UB,因为12.7/5表示
如果typeid的操作数引用了正在构造的对象,或者销毁,并且操作数的静态类型既不是构造函数或析构函数的类或其基之一,的结果typeid未定义
对吧?
我猜是UB。看看C
的构造函数。
C()
: // 1
B(this) // 2
{ // 3
...
每个对象都应该有一些关于它的类型信息,所以我们可以猜测构造函数初始化它
正如您所知,标准为实现提供了很大的自由度。也许它并没有决定构造函数应该在// 1
还是// 3
中初始化typeinfo。如果一个实现决定在// 3
中初始化它,您将得到错误的结果,因为typeinfo没有在// 2
中初始化。
(然而,VC++2013和g++4.8.3都给出了正确的结果。请注意>o<)
我是对的。得到正确结果的原因是C
没有虚函数 正如您所知,如果没有虚拟功能,RTTI就不会启用。所以编译器从静态类型生成了typeinfo,即C
。
通过虚拟函数,它生成UB的结果。
struct B
{
long unsigned int hash;
B(C *c);
virtual ~B() = default; // here.
};
(实例)
我不认为这是未定义的行为。
上一句话说
typeid
用于。。。一个名为…的函数。。。来自构造函数如果typedid
的操作数指的是正在构造的对象。。。,CCD_ 12产生表示构造函数的类的CCD_。
正在构建的相关对象是c
,而typeid
的操作数的静态类型是C,因此结果是C的类型。
B构造函数也在运行,但c
不是"正在构建的对象",因此您引用的句子不适用。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 通过reinterpret_casting方法指针从指针调用派生类的方法。这是 UB 吗?
- 为什么从构造函数对纯虚函数的虚拟调用是 UB,而标准允许调用非纯虚函数
- 具有typeid调用的UB
- 为什么使用 'std::reverse_iterator' 不会调用 UB?
- 如果从析构函数调用纯虚函数是UB,为什么可以使用纯虚析构函数?
- 函数调用中的临时:UB