typeid 中的表达式在运行时被评估两次?
expression in typeid is evaluated twice in runtime?
请注意,typeid 运算符中的表达式如果是具有虚拟成员的类型的左值,将在运行时进行计算。
我有一个琐碎的Base
class如下
class Base
{
public:
Base(const std::string &s):sval(s){}
virtual ~Base()=default;
private:
std::string sval;
};
和 return Base 左值的简单函数如下:
Base& ChangeBase(Base &b)
{
std::cout<<"Called"<<std::endl;
return b;
}
当我编写以下代码来检查 typeid 运算符时:
int main()
{
Base b("Dream");
typeid (ChangeBase(b));
return 0;
}
我得到以下输出:
Called
Called
说明函数ChangeBase
被调用了两次,那是不是意味着typeid中的表达式会在运行时被求值两次(如果需要在运行时求值)?如果是,为什么?
我正在使用 gcc 4.9.3
GCC 首先检查值是否为 null,然后再次对其进行评估,并且仅在此之后调用 typeid。
程序集:https://godbolt.org/g/SoLFYq
lea rax, [rbp-64]
mov rdi, rax
call ChangeBase(Base&)
test rax, rax
je .L8
lea rax, [rbp-64]
mov rdi, rax
call ChangeBase(Base&)
...
.L8:
call __cxa_bad_typeid
请注意,typeid 运算符中的表达式如果是具有虚拟成员的类型的左值,将在运行时进行计算。
我有一个琐碎的Base
class如下
class Base
{
public:
Base(const std::string &s):sval(s){}
virtual ~Base()=default;
private:
std::string sval;
};
和 return Base 左值的简单函数如下:
Base& ChangeBase(Base &b)
{
std::cout<<"Called"<<std::endl;
return b;
}
当我编写以下代码来检查 typeid 运算符时:
int main()
{
Base b("Dream");
typeid (ChangeBase(b));
return 0;
}
我得到以下输出:
Called
Called
说明函数ChangeBase
被调用了两次,那是不是意味着typeid中的表达式会在运行时被求值两次(如果需要在运行时求值)?如果是,为什么?
我正在使用 gcc 4.9.3
GCC 首先检查值是否为 null,然后再次对其进行评估,并且仅在此之后调用 typeid。
程序集:https://godbolt.org/g/SoLFYq
lea rax, [rbp-64]
mov rdi, rax
call ChangeBase(Base&)
test rax, rax
je .L8
lea rax, [rbp-64]
mov rdi, rax
call ChangeBase(Base&)
...
.L8:
call __cxa_bad_typeid