У нас есть макрос для сигнализации об ошибках в общей библиотеке утилит, который выглядит следующим образом:
#define OurMacro( condition ) \
if( condition ) { \
} else { \
CallExternalFunctionThatWillThrowAnException( parametersListHere ); \
} \
То, что я называю parametersListHere
- это список констант и макросов, разделенных запятыми, который заполняется компилятором при каждом расширении макроса.
Этот вызов функции всегда преобразуется в вызов - реализация функции не предоставляется компилятору. Функция имеет шесть параметров, и в конфигурации отладки все они имеют значимые значения, в то время как в конфигурации выпуска только два имеют значащие значения, а другим передаются те же значения по умолчанию.
Обычно условие выполняется, поэтому мне все равно, насколько быстро выполняется вызов, меня интересует только раздувание кода. Для вызова этой функции с 6 параметрами требуется семь инструкций x86 (6 push
es и одна call
), и ясно, что 4 из этих push
es можно избежать, если сигнатура функции имеет только два параметра - это может быть сделано путем введения промежуточной функции "gate", реализованной таким образом, что ее реализация не видна компилятору.
Мне нужно оценить, должен ли я настаивать на этом изменении. Пока что основное улучшение, на которое я рассчитываю, заключается в том, что при уменьшении количества параметров при каждом вызове будет сброшено 4 инструкции, что означает, что код, окружающий расширение макроса, станет меньше, и компилятор с большей вероятностью встроит его в код и будет оптимизировать выдаваемый код. *
Как я могу оценить это, фактически не пытаясь и перекомпилируя весь наш код и тщательно анализируя полученный код? Каждый раз, когда я читаю о inline
, появляется утверждение, что компилятор решает, следует ли встроить функцию.
Могу ли я увидеть какой-то точный набор правил того, как внутренние функции функции влияют на решение компилятора при вставке?