14.1  Встраиваемые функции

Как уже указывалось, в программах на языке С директива препроцессора #define хотя и используется для определения макро­определений, но иногда приводит к ошибкам, которые нелегко отыски­вать. Недостатком макроопределения является также то, что в нем нельзя опреде­лить локальные переменные. По этой же причине при обработке такого макровызова не выполняются проверка и преобразование типов аргументов.

В языке C++ для определения функции, которая должна встраиваться как макрорасширение (встраиваемая функция), используется ключевое слово inline. При определении и использовании встраиваемой функции надо придерживаться некоторых правил:

1) определение и объявление функции inline должны быть со­вмещены и располагаться перед первым вызовом этой функции (т.е. если появится объявление функции с ключевым словом inline и без тела функции (т.е. прототип функции), компилятор выдаст соответствующее сообще­ние об ошибке);

2) имеет смысл определять с ключевым словом inline только очень маленькие функции, так как большие функции значительно удлиняют объектный код и замедляют компиляцию (хотя при этом увеличивается скорость выполнения);

3) надо помнить, что ключевое слово inline является лишь реко­мендацией компилятору, что данную функцию надо сделать встра­иваемой. Компилятор же сам решает, будет функция встраиваемой или нет. При этом он руководствуется, во-первых, размером функ­ции (некоторые компиляторы позволяют делать встраиваемыми функции длиной до 1200 строк). Во-вторых, если функция содер­жит рекурсивный вызов, то встраиваемым может быть лишь пер­вый вызов. И наконец, в-третьих, в некоторых реализациях в теле встраиваемой функции нельзя использовать операторы цикла for, while, do, break, continue. Соответствующее предупреждение, что функция будет обычной, а не встраиваемой, выдается не во всех реализациях, поэтому программист может даже не догадываться, что функция окажется обычной, а не встраиваемой.

Таким образом, использование ключевого слова inline для опре­деления встраиваемых функций и ключевого слова const для объ­явления символических констант позволяет полностью исключить директиву препроцессора #define из употребления.