Могут ли современные компиляторы оптимизировать константные выражения, производные от функции?

Насколько я понимаю, современные компиляторы С++ используют ярлыки для таких вещей, как:

if(true)
{do stuff}

Но как насчет чего-то вроде:

bool foo(){return true}
...
if(foo())
{do stuff}

Or:

class Functor
{

 public:
        bool operator() () { return true;}

}

...

Functor f;

if(f()){do stuff}

person QuarterlyQuotaOfQuotes    schedule 21.12.2012    source источник
comment
Современные оптимизаторы оптимизируют конструкции, которые намного сложнее...   -  person krlmlr    schedule 21.12.2012
comment
Это подпадает под предсказание ветвления.   -  person andre    schedule 21.12.2012
comment
..как это часто очень плохое название.   -  person    schedule 21.12.2012
comment
@ahenderson, нет, это шаг за пределы предсказания ветвления. Это компилятор, полностью исключающий ветвь. Вероятно, более очевидно, когда условие ложно, так как вложенный код будет полностью опущен.   -  person Mark Ransom    schedule 21.12.2012
comment
@MarkRansom Это действительно интересно.   -  person andre    schedule 21.12.2012


Ответы (3)


Это зависит от того, может ли компилятор увидеть foo() в той же единице компиляции.

При включенной оптимизации, если foo() находится в той же единице компиляции, что и вызывающие, он, вероятно, встроит вызов foo(), а затем оптимизация будет упрощена до той же проверки if (true), что и раньше.

Если вы переместите foo() в отдельную единицу компиляции, встраивание больше не может происходить, поэтому большинство компиляторов больше не смогут оптимизировать этот код. (Оптимизация времени компоновки может быть оптимизирована для разных единиц компиляции, но она встречается гораздо реже — не все компиляторы ее поддерживают и в целом она менее эффективна.)

person StilesCrisis    schedule 21.12.2012

Я только что попробовал g++ 4.7.2 с -O3, и в обоих примерах он оптимизирует вызов. Без -O это не так.

person NPE    schedule 21.12.2012

Современные компиляторы невероятно умны и часто выполняют «оптимизацию всей программы». Поэтому, пока вы делаете разумные вещи, это определенно оптимизирует вызовы функций, которые просто возвращают постоянное значение. Компилятор также будет встраивать код, который вызывается только один раз [даже если он очень большой], поэтому писать маленькие функции вместо больших определенно стоит. Конечно, используя функцию несколько раз, она может не быть встроена, но тогда вы получите лучшую скорость попадания в кеш, вызывая одну и ту же функцию из двух мест и в целом меньший код.

person Mats Petersson    schedule 21.12.2012