Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > inline вариации стандарта C99 и GNU


Автор: null56 18.3.2010, 11:50
Всем привет
Заинтересовался одним вопросом по поводу модификаторов встаиваемых фукнций (inline) для стандартов C99 и GNU

Первое что меня смутило, так это отрывок из книги
Цитата

Функции с подстановкой тела объявляются с помощью ключевых слов staic и inline в декларации функции. Например,
Код

static inline void dog(unsigned long tail_size);

Декларация функции должна быть описана перед любым ее вызовом, иначе под-
становка тела не будет произведена. Стандартный прием — это размещение функций
с подстановкой тела в заголовочных файлах. Поскольку функция объявляется как
статическая (static) , экземпляр функции без подстановки тела не создается. Если
функция с подстановкой тела используется только в одном файле, то она может
быть размещена в верхней части этого файла.

Вопрос: если функция объявлена, как inline, то она будет встраиваемой только в том модуле (или единице трансляции) где определена. В случае вызова ее из другого модуля, будет создан код функции и она станет невстраиваемой. Чтобы этого избежать, надо объявлять как статик, тогда ее можно будет вызывать в других модулях и она до сих пор останется встраиваемой. Я правильно понял изложения автора???

Но позже я нарвался на статью
http://www.greenend.org.uk/rjk/2003/03/inline.html
тут рассматриваются еще вариации использования встраиваемых функций (раздел стандарта C99) и если я правильно перевел текст, то мои выводы следующие:
inline - значит встраиваемая только в том модуле, где объявлена и определена, для других модулей ВООБЩЕ не доступна
extern inline - встраиваемая только в том модуле, где опредлена и объявлена, но код создается, так что ее можно дергать из других модулей, где она уже будет НЕВСТРАИВАЕМОЙ
static inline - вообще не понял отличие от обычной inline

Помогите пожалуйста, что имел в виду автор книги, цитату которой я привел и как же всё таки модификаторы inline, inline extern, static inline воздействуют на вызовы и доступность функций в родном и внешних модулях?

ЗЫ: Каким же стандартом руководствуются разработчики ядра linux?
потому что вот ядерный хедер
Код

static inline bool strstarts(const char *str, const char *prefix)
{
        return strncmp(str, prefix, strlen(prefix)) == 0;
}



Заранее благодарен за помощь

Автор: djamshud 18.3.2010, 12:38
static говорит о том, что за пределы текущего .c-файла использование некоторого объекта (не в с++-ном смысле), в т.ч. функции, не выйдет. И что мы имеем: файл1.с включает хедер с функцией, объявленной как inline, файл2.с тоже включает его. Если она static - ее код скопируется и заинлайнится в оба объектных файла, порожденных компиляцей файла1 и файла2.

Вообще советую поэксперементривать с этим самому, понимание тут же придет.

Автор: null56 18.3.2010, 12:41
Вот чего мне MAKCim ответил:
Цитата

если *.h файл со static inline подключается к *.c файлу и соответствующая функция не подставляется компилятором, то она становится просто статической функцией данного *.c модуля => не возникает ошибки двойного определения, если *.h файл подключается в более чем один *.c файл

по сути тоже самое

Автор: bsa 18.3.2010, 14:15
null56, ты только помни, что inline - это СОВЕТ компилятору сделать функцию встраиваемой. Он этот совет может молча проигнорировать, что с успехом и делает при отключении оптимизации. В С++ код функции с модификатором inline, которая используется в нескольких единицах трансляции, но не встроенная, будет только в одном месте файла. Если ты сделаешь static inline, то код будет во всех единицах. В Си, если я не ошибаюсь, поведение inline несколько отличается, поэтому там без static ее использовать в хидерах проблематично.

Автор: null56 18.3.2010, 14:19
про остальные вариации с учетом ключевой фразы: __КОМПИЛЯТОР_НЕ_ГАРАНТИРУЕТ_ПОДСТАНОВКУ
inline
Цитата

// a declaration mentioning inline
inline int max(int a, int b);

// a definition mentioning inline
inline int max(int a, int b) {
  return a > b ? a : b;
}

The function won't be callable from other files; if another file has a definition that might be used instead.

получается по возможности встраивается в текущий модуль и НЕ может быть вызвана из других, если в других нет определения

inline extern
Цитата

A function where at least one declaration mentions inline, but where some declaration doesn't mention inline or does mention extern. There must be a definition in the same translation unit. Stand-alone object code is emitted (just like a normal function) and can be called from other translation units in your program.

The same constraint about statics above applies here, too.

In this example all the declarations and definitions use inline but one adds extern:

// a declaration mentioning extern and inline
extern inline int max(int a, int b);

// a definition mentioning inline
inline int max(int a, int b) {
  return a > b ? a : b;
}

тут ситуация такая: функция может быть подставлена в текущий модуль, но в то же время создается объектный код, который смогут дергать из других модулей

вот так я это понял, если есть чего добавить, отпишитесь пожалуйста

а пока, спасибо за помощь

ЗЫ: bsa, да, согласен, речь об этом и шла (о языке Си)... Максим мое внимание устремил именно на ключевое слово СОВЕТ КОМПИЛЯТОРУ

Автор: MAKCim 19.3.2010, 11:53
null56
для полного понимания просто сделай пару примеров и скомпилируй с -std=c99

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)