gcc -O0
не включает -finline-functions
, поэтому, даже если функции находятся в одном файле, он не будет пытаться. См. Также Почему этот класс-оболочка C ++ не выделен? . (Не пытайтесь использовать __attribute__((always_inline))
: вы получите встраивание, ничего не оптимизируется.
С помощью gcc -O3 -fwhole-program *.cpp
вы можете сделать что-то встроенное, чтобы включить встраивание в исходные файлы. (Независимо от того, были ли они объявлены inline
или нет, компилятору решать, что лучше).
Суть inline
состоит в том, чтобы сообщить компилятору, что ему не нужно выдавать отдельное определение функции, если он решит встроить ее во всех вызывающих. (Поскольку определение, а не просто объявление этой функции будет появляться во всех единицах перевода, которые ее используют. Поэтому, если какой-то другой файл решит не вставлять его, определение может быть передано туда.)
Современные компиляторы все еще используют свою обычную эвристику, чтобы решить, стоит ли вставлять или нет. например большая функция с несколькими вызывающими, вероятно, не будет встроена, чтобы избежать раздувания кода. static
сообщает компилятору, что никакой другой модуль перевода не может видеть функцию, поэтому, если в этом файле есть только один вызывающий объект, он, скорее всего, будет там встроен. (Если у вас есть большая функция, плохая идея сделать ее static inline
. Вы получите копию определения в каждом файле, где она не встроена, и слишком агрессивная вставка. Для небольшой функции, которая, вероятно, будет для повсеместного встраивания, вам, вероятно, все равно следует просто использовать inline
, а не static inline
, поэтому в случае, если что-либо займет адрес функции, для всех файлов будет использоваться только одно определение. inline
говорит компоновщику объединить повторяющиеся определения функции вместо ошибок. Это поведение является одной из наиболее важных частей того, что на самом деле делает inline
, а не фактической подсказкой компилятору, что вы хотите, чтобы он был встроен.)
gcc -fwhole-program
(со всеми исходными файлами в одной командной строке) дает компилятору достаточно информации, чтобы принять все эти решения самостоятельно. Он может видеть, есть ли у функции только один вызывающий объект во всей программе, и встроить его вместо создания отдельного определения, настройки arg и call
.
.
gcc -flto
позволяет оптимизировать время соединения, аналогично целой программе, но не требует всех файлов .cpp
в командной строке одновременно. Вместо этого он сохраняет код GIMPLE в файлах .o
и завершает оптимизацию во время ссылки.