具有typeid调用的UB

时间:2014-08-30 11:38:19

标签: c++ undefined-behavior typeid

我已经为理解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未定义

右?

2 个答案:

答案 0 :(得分:0)

我猜是UB。看看C的构造函数。

C()
    :            // 1
      B(this)    // 2
{                // 3
    ...

每个对象应该有关于它的typeinfo的东西,所以我们可以猜测构造函数初始化它。

如您所知,标准为实现提供了很大的自由度。也许它没有决定构造函数是否应该在// 1// 3中初始化typeinfo。如果一个实现决定在// 3中初始化它,那么你会得到错误的结果,因为在// 2中没有初始化typeinfo。


(但是,VC ++ 2013和g ++ 4.8.3都给出了正确的结果。请注意&gt; o&lt;)

我是对的。原因we could get correct result C没有虚函数。如您所知,如果没有虚函数,则RTTI不会启用。因此编译器从静态类型生成了typeinfo,即C

使用虚函数,它会生成UB的结果。

struct B
{
    long unsigned int hash;

    B(C *c);

    virtual ~B() = default; // here.
};

(live example)

答案 1 :(得分:0)

我不认为这是不确定的行为。

上一句话说

  

在......中使用typeid来自构造函数的函数   ...,如果typedid的操作数引用正在构造的对象...,typeid产生代表构造函数类的std::type_info

正在构建的相关对象是ctypeid的操作数的静态类型是C,因此结果是C的类型。

B构造函数也在运行,但c不是&#34;正在构建的对象&#34;那里,你所引用的句子不适用。