В последнее время я обсуждал достоинства "современных" языков по сравнению с С++ с некоторыми друзьями, когда появилось следующее (я думаю, вдохновленный Java):
Создает ли какой-либо компилятор С++ динамическую отправку из цикла? Если нет, существует ли какая-либо конструкция, которая позволила бы автору заставить (или сильно поощрять) такую оптимизацию?
Вот пример. Предположим, что у меня есть полиморфная иерархия:
struct A { virtual int f() { return 0; } };
struct B : A { virtual int f() { return /* something complicated */; } /*...*/ };
Теперь у меня есть цикл, который накапливает f()
:
int acc(const A * p, unsigned int N)
{
int result = 0;
for (unsigned int i = 0; i != N; ++i)
result += p->f(); // #1
return result;
}
В этой функции динамическая отправка p->f()
появляется во время каждого цикла цикла. Однако конечная цель отправки вопиюще (?) Не может меняться.
Вопрос: Эта динамическая отправка оптимизируется компилятором? Если нет, есть ли способ переписать код, чтобы заставить эту оптимизацию, или, по крайней мере, позволить компилятору распознать это? Есть ли хороший тестовый код, который может быстро сказать, будет ли это уже оптимизировано?
Меня интересуют ответы на язык и реализацию, например "это невозможно в соответствии со стандартом", или "да, MSVC делает это с опцией /xyzzy
".
Некоторые сравнительные замечания: очевидно, что Java оптимизирует и даже строит вызов во внутреннем цикле, если это необходимо. Objective-C ++, по-видимому, позволяет запросить указатель динамической функции и сохранить его.
Разъяснение: основной случай использования, который мне интересен, - это когда базовый класс и функция с циклом (например, накопитель) являются частью отдельной единицы перевода или библиотеки, и нет контроля или знания производные классы.