Можно ли вообще заставить любой компилятор C ++ сделать это?
Возможно, не напрямую - это проблема качества реализации.
Оба Clang и G CC (для последних протестированных версий), сделайте это со стандартным флагом -O3
. На самом деле, они даже делают это с -O1
и -O2
... вы должны полностью отключить оптимизацию, чтобы они отправили вызов на ExpensiveFunction
.
Быстрая попытка с x64 MSV C 19.24 показывает, что он также оптимизирует вызов, по крайней мере с /O2
.
MSV C перечислены параметры командной строки здесь .
G CC параметры командной строки приведены в руководстве, параметры оптимизации c здесь указаны .
В общем, вы можете видеть, что несколько разных компиляторов делают с одним и тем же кодом одновременно с Мэттом Годболтом. Проводник компилятора, например , поэтому .
Обратите внимание, что это только тестирование вашего примера кода - если ExpensiveFunction
имеет наблюдаемые побочные эффекты, оптимизатор не сможет удалить его.
Редактировать , поэтому получается, что ExpensiveFunction
имеет наблюдаемые побочные эффекты.
Я понимаю, что Оптимизация, которая удаляет вызов ExорогоFunction, может быть деструктивной оптимизацией,
Не существует такой вещи, как «деструктивная оптимизация». Оптимизация - это то, что улучшает нефункциональные характеристики вашей программы (обычно производительность или размер) без изменения функциональных характеристик , которые специально определены как видимые побочные эффекты.
Давайте рассмотрим Ваш заголовок, исправленный в соответствии с основной частью вопроса:
Существуют ли параметры компилятора C ++, которые позволяют агрессивно удалять все вызовы функций и передаваться в аргументах функциям с непустыми тел?
Если компилятор свободен ускорить ваш код, отбрасывая вещи, которые занимают время , даже если они имеют наблюдаемый извне эффект , жизнь становится очень простой: это можно просто заменить каждую программу на
int main() {}
и назвать ее «разрушительной оптимизацией». Это правильное решение для вашего исправленного заголовка, верно?
... но я чувствую, что это должно быть возможно без преобразования печати в макрос, который будет скомпилирован в наиболее оптимизированной конфигурации.
Можно также сделать условное тело ExpensiveFunction
условным, если, например, это действительно отладочный вывод, наблюдаемый побочный эффект которого вы хотите отключить в некоторых сборках
int ExpensiveFunction() {
#ifndef DEBUG
// Do expensive calculation
// ...
std::cout << "You shouldn't see this!" << std::endl;
#endif
return 42;
}
Но отключение кода с видимыми побочными эффектами должно всегда находиться под вашим ручным управлением, если вы не довольны моей сверхредуктивной оптимизацией всей программы выше.