typeid中的表达式在运行时被评估两次?

时间:2016-11-24 07:35:55

标签: c++ typeid

请注意,如果typeid运算符是具有虚拟成员的类型的左值,则它将在运行时计算。

我有一个简单的Base课程如下

class Base
{
public:
    Base(const std::string &s):sval(s){}
    virtual ~Base()=default; 
private:
    std::string sval;
};

和一个简单的函数来返回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

1 个答案:

答案 0 :(得分:2)

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