Что такое inline в C++
Что проверяют
Знаете ли вы современный смысл inline: это правило одного определения, а не приказ встраивать код. Кандидата, который отвечает только «функция вставляется в место вызова», сразу спрашивают, почему компилятор тогда встраивает функции без этого слова и как inline связан с заголовками.
Как отвечать
Исторически inline был подсказкой оптимизатору. Сейчас решение о встраивании компилятор принимает по своей эвристике: встраивает небольшие функции без inline и может не встроить помеченные. С LTO он делает это даже между единицами трансляции.
Что ключевое слово даёт сегодня:
- исключение из ODR:
inline-функцию можно определить в нескольких единицах трансляции, если определения одинаковы. Поэтому функцию, определённую в заголовке, помечаютinline, иначе при подключении заголовка в два.cppбудет ошибка линковкиmultiple definition; - одна сущность на программу: у
inline-функции один адрес и одна копия статической локальной переменной во всех единицах трансляции; - неявно inline: методы, определённые внутри тела класса, функции
constexprиconsteval. У шаблонов своё правило, для них ODR ослаблено и без ключевого слова; - inline-переменные (C++17):
inline constexpr int kLimit = 64;в заголовке иstatic inline int counter = 0;прямо в классе, без отдельного определения в.cpp. Статическиеconstexpr-члены класса с C++17 тоже неявно inline.
Для принудительного встраивания есть расширения компиляторов: [[gnu::always_inline]] в GCC и Clang, __forceinline в MSVC. Обратное делают через noinline.
Если спросят про макросы: inline-функция проверяет типы, вычисляет аргументы один раз и видна отладчику.
Где спотыкаются
Утверждают, что inline гарантирует встраивание, а его отсутствие запрещает. Ни то, ни другое не верно.
Путают inline и static в заголовке. static даёт каждой единице трансляции свою копию с отдельным адресом и своими статическими переменными, inline даёт одну общую.
Допускают разные определения одной inline-функции в разных файлах, например из-за разных макросов. Это нарушение ODR и неопределённое поведение, а линкер его обычно не замечает.