编译器是否消除了不必要的“dynamic_cast”

Does the compiler eliminate unnecessary `dynamic_cast`s?

本文关键字:dynamic cast 不必要 是否 编译器      更新时间:2023-10-16

我正在编写一个繁重的模板化应用程序。在它的某个地方,有一些类似的代码:

class TA {  };
class TX {
public:
    template <typename T>
    T &Foo(int a) {
        TA *pta;
        // here somehow initialize pta
        return *(dynamic_cast<T*>(pta));
    }
};

如果我用T = TA调用Foo模板成员函数,编译器是否会消除或优化动态转换dynamic_cast<TA*>(pta)[其中pta的类型为TA*]?还是我应该制作一些type_traits魔术来手动消除它?

是的,如果编译器能够确定强制转换总是成功的,那么它将省略运行时检查。在你的情况下,由于演员阵容微不足道,所以不会失败。

如果类型相同,则根本不进行转换。在C++标准中,5.2.7:

dynamic_cast<T>(v)

如果v的类型与T相同,或者它与T相同——除了T中的类对象类型比v中的类目标类型更具cv限定性之外,结果是v(必要时转换)

如果要转换为的类型是指向子类的指针或引用,则也没有运行时检查:

如果T是"指向cv1 B的指针",v的类型为"指向cv2 D的指针"使得B是D的基类,则结果是指向v所指向的D对象的唯一B子对象的指针。

您已经编写了一个模板,而不是简单的代码,这不会改变优化决策。你的代码相当于这个:

struct S {};
S *foo(S *a)
{
    return dynamic_cast<S*>(a);
}

具有基本优化的(g++ -O1)将编译为:

S *foo2(S *a)
{
    return a;
}