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

441
23 ноября 2017, 03:58

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

Answer 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-определение этой функции - то компилятор имеет право сам выбрать, какое определение вызывать.

READ ALSO
Изменение размера map

Изменение размера map

Мяч находится на игровом поле m на n в ячейке (i, j), его можно передвигать Найдите количество возможных путей вывода мяча за пределы игрового...

302
Скриншот рабочего стола Windows при отсутствии залогиненного пользователя (С++)

Скриншот рабочего стола Windows при отсутствии залогиненного пользователя (С++)

На удалённом сервере запущена программа, деятельность которой хочется мониторить через централизованную систему наблюденияВместе с ней...

289
C++ Poco Отправка post запроса

C++ Poco Отправка post запроса

Пытаюсь отправить запрос post но не получается, Get приходит а post нет

436
Узнать загруженность CPU C++

Узнать загруженность CPU C++

Здравствуйте, пытаюсь разбираться с WIN32 API, реши написать что-то на подобии диспетчера задач, но никак не могу понять как узнать нагруженность...

554