Napisałem ten krótki program, aby sprawdzić, jak działa devirtualization. Kompilator powinien być w stanie wywnioskować, o typieDevirtualization kompilatora, niezbyt inteligentny?
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
void foo() { cout << "Base::foo" << endl; }
virtual void bar() { cout << "Base::bar" << endl; }
virtual ~Base() = default;
};
class Child : public Base
{
public:
void foo() { cout << "Child::foo" << endl; }
void bar() { cout << "Child::bar" << endl; }
};
int main()
{
Base* obj = new Child;
obj->foo();
obj->bar();
delete obj;
}
skompilowany z -O2 -std=c++11
gcc 5.3, 3.7 za pomocą szczęk https://gcc.godbolt.org/.
Co okazało się, że ani kompilator był w stanie zoptymalizować wszystko - gcc inlines foo()
i sprawia, że wirtualny wezwanie do bar()
podczas dzyń sprawia wezwanie do foo()
i devirtualizes i inlines zadzwonić do bar()
.
Tymczasem, jeśli zamiast zadzwonić obj->bar();
a następnie obj->foo();
, kompilatory nie mają problemu w optymalizacji - dzyń inlines oba połączenia i gcc sprawia zwykłe połączenie do bar()
zamiast wirtualnego jednego i inlines foo()
.
Czy ktoś może wyjaśnić to zachowanie?
to pytanie jest dziwne. na co mamy odpowiedzieć? GCC jest gorszy niż Clang? czasami kompilatorzy mogą wymyślać rzeczy, czasami tęsknią. Clang jest nowszy i został zbudowany od podstaw, aby obsługiwać tego rodzaju optymalizacje. –
Nie, jestem ciekawy, czy jest coś wyjątkowego poza tą gorszą optymalizacją w przypadku, gdy wywołanie inne niż wirtualne jest wykonywane jako pierwsze. Niektóre optymalizacje są już wykonywane, które zakłócają devirtualization? – cailinscath
http://hubicka.blogspot.de/2014/04/devirtualization-in-c-part-5-feedback.html dostarcza interesujących informacji podstawowych dotyczących gcc. Jest to cały poważny artykuł o devirtualization od dewelopera gcc, który zaimplementował go. Czy próbowałeś dodać "-fwhole-program" lub "-fsuggest-final-methods" do gcc? – Jens