Тонкости и хитрости в вопросах и ответах
Как встроенные функции могут влиять на соотношение безопасности и скорости?
В обычном С вы можете получить «инкапсулированные структуры», помещая в них указатель на void, и заставляя его указывать на настоящие данные, тип которых неизвестен пользователям структуры. Таким образом, пользователи не знают, как интерпретировать эти данные, а функции доступа преобразуют указатель на void к нужному скрытому типу. Так достигается некоторый уровень инкапсуляции.
К сожалению, этот метод идет вразрез с безопасностью типов, а также требует вызова функции для доступа к любым полям структуры (если вы позволили бы прямой доступ, то его мог бы получить кто угодно, поскольку будет известно, как интерпретировать данные, на которые указывает void*. Такое поведение со стороны пользователя приведет к сложностям при последующем изменении структуры подлежащих данных).
Стоимость вызова функции невелика, но дает некоторую прибавку. Классы С++ позволяют встраивание функций, что дает вам безопасность инкапсуляции вместе со скоростью прямого доступа. Более того, типы параметры встраиваемых функций проверяются компилятором, что является преимуществом по сравнению с сишными #define макросами.
Зачем мне использовать встроенные функции? Почему не использовать просто #define макросы?
Поскольку #define макросы опасны.
В отличие от #define макросов, встроенные (inline) функции не подвержены известным ошибкам двойного вычисления, поскольку каждый аргумент встроенной функции вычисляется только один раз. Другими словами, вызов встроенной функции — это то же самое что и вызов обычной функции, только быстрее:
// Макрос, возвращающий модуль (абсолютное значение) i #define unsafe(i) \
( (i) >= 0 ? (i) : (i) )
// Встроенная функция, возвращающая абсолютное значение i inline
int safe(int i)
{
return i >= 0 ? i : i;
}