Страницы

Поиск по вопросам

среда, 1 января 2020 г.

Inline функции в C и С++

#cpp #c


В чем разница inline функций в C и C++? Желательно со ссылкой на стандарт.
    


Ответы

Ответ 1



Как в С так и в С++ ключевое слово inline не гарантирует встраивания функции в вызывающий код, а является лишь пожеланием компилятору, что данная функция должна вызываться настолько быстро, насколько возможно. Поэтому осязаемым эффектом ключевого слова inline является только то, как оно влияет на правила объявления и определения функций. Если рассматривать функции с внутренним связыванием, т.е. функции, объявленные как static inline, то разницы между C и С++ фактически нет (если я ничего не упускаю). Однако как только речь заходит о функциях с внешним связыванием, то разница между языками довольна значительна. В С++ правила просты: допускаются множественные определения inline функций (в разных единицах трансляции). При этом если функция объявлена inline в одной единице трансляции, то и во всех остальных единицах трансляции, где она объявлена, она должна быть объявлена именно inline. Во всех единицах трансляции, где эта функция определена, она должна быть определена одинаково. В языке С же проводится довольно запутанное деление между inline-определениями функции и external-определениями функции. Inline-определение возникает тогда, когда в данной единице трансляции все объявления данной функции сделаны с ключевым словом inline, но ни одно не содержит ключевого слова extern. В такой ситуации определение функции не создает внешнего символа - к нему нельзя прилинковаться из другого объектного файла. В inline-определениях запрещается определять модифицируемые статические объекты и thread-локальные объекты. Также оттуда нельзя ссылаться на сущности (объекты и функции) с внутренним связыванием. External-определение возникает тогда, когда в данной единице трансляции либо есть "обычное" объявление функции (без inline), либо объявление сразу с двумя ключевыми словами extern inline. External-определение является обычной функцией - оно порождает внешний символ к которому можно прилинковаться из другого объектного файла - достаточно сделать там объявление этой функции.   Например inline void foo(); // Объявление inline void bar(); // Объявление inline void foo() // Определение { static int i = 42; } inline void bar() // Определение { static int j = 42; // Ошибка! } void foo(); // Объявление inline void bar(); // Объявление В данном примере определение функции bar является ошибочным, т.к. это inline-определение, а в inline-определениях нельзя определять модифицируемые статические объекты. В то же время определение функции foo является external-определением потому, что ниже по тексту встречается объявление это функции без слова inline. На такое определение никаких ограничений не накладывается. Далее Если в какой-то единице трансляции наличествует inline-определение функции, и нигде в проекте нет extern-определения этой функции - то вызываться будет именно inline-определение. Если в какой-то единице трансляции наличествует inline-определение функции, и где-то в проекте есть extern-определение этой функции - то компилятор имеет право сам выбрать, какое определение вызывать.

Комментариев нет:

Отправить комментарий