我已经编写了理解 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 说
If the operand of typeid refers to the object under construction or destruction and the static type of the operand is neither the constructor or destructor’s class nor one of its bases, the result of typeid is undefined
对吧?
最佳答案
我猜是UB。查看 C
的构造函数。
C()
: // 1
B(this) // 2
{ // 3
...
每个对象都应该有一些关于它的类型信息,所以我们可以猜测构造函数初始化它。
如您所知,标准为实现提供了很大的自由度。也许它没有决定构造函数是否应该在 //1
或 //3
中初始化 typeinfo。如果一个实现决定在 //3
中初始化它,您会得到错误的结果,因为 typeinfo 没有在 //2
中初始化。
(但是,VC++ 2013 和 g++ 4.8.3 都给出了正确的结果。请注意 >o<)
我是对的。原因we could get correct result是 C
没有虚函数。 如您所知,如果没有虚函数,则不会启用 RTTI。因此编译器从静态类型生成类型信息,即 C
。
使用虚函数,它生成 UB 的结果。
struct B
{
long unsigned int hash;
B(C *c);
virtual ~B() = default; // here.
};
关于c++ - 带有 typeid 调用的 UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25581948/