Ситуация такая: есть inline-функция — член класса. Она вызывается только из других функций-членов того же класса. Обязательно ли ее определение должно располагаться раньше всех вызовов, т.е. раньше определений всех остальных методов класса? Или может просто запихать ее в h-файл, если по-другому нельзя?
И вообще, кому-нибудь достоверн известно, сильно подставляемые функции ускоряют работу?
Буду благодарен, если кто-нибудь поделится информацией
Здравствуйте Dancer, Вы писали:
D>Ситуация такая: есть inline-функция — член класса. Она вызывается только из других функций-членов того же класса.
Это несущественно.
D>Обязательно ли ее определение должно располагаться раньше всех вызовов, т.е. раньше определений всех остальных методов класса?
Вовсе нет.
D>Или может просто запихать ее в h-файл, если по-другому нельзя?
Или в h-файл, или в в срр-файл (в этом случае не забыть добавить inline)
D>И вообще, кому-нибудь достоверн известно, сильно подставляемые функции ускоряют работу?
Все зависит от того, насколько часто встречаются вызовы этой функции. Если она в процессе работы вызывается пару раз, то никакого выигрыша, естественно не будет.
Если же она вызывается часто, а тело простое, то выигрыш может быть существенным.
Здравствуйте Fiend, Вы писали:
F>//a.cpp F> inline void A::Some()const{}
F>Если да, то пробовал ли скомпилить/скомпоновать?
Ну, допустим. Ты не смог?
Если эту функцию вызывать только внутри этого cpp-шника, то она встроится при оптимизации и даст прирост производительноси. А вот если ее вызвать где-то снаружи, то компилятор, не, даже линкер, выдаст Unresolved external для всех других единиц компиляции, в которых эта функция не объявлена.
Так-что, те 2 функции, из которых вызвается эта, определены в том-же cpp-шнике, что и наша заинлайненая функция, то все будет OK. Вот если в другом — тогда трабл.
F>Само собой, такое я пробовал. А ты уверен, что она встроилась? Как это проверить?
Уверенным тут быть нельзя т.к. насколько я помню стандарт не гарантирует того что inline функция всегда будет встраиваться. inline это всего лишь подсказка компайлеру, говорящая что эту функцию надо по возможности встроить.
В случау с рекурсивным вызовом inlineовость проблематична
А проверить можно посмотрев сгенерированный код.Будет там call или нет.
Здравствуйте Fiend, Вы писали:
F>А ты уверен, что она встроилась? Как это проверить?
Нет. Я не уверен. Более того тебе скажу: в проекте с отключенным инлайнингом функции не встраиваются. Если же инлайнинг включен, то, встраивать функцию или нет — дело компилятора.
inline — всего лишь просьба по возможности сделать функцию встроенной. Она может быть не выполнена компилятором.
На примере компилятора VC могу сказать, что каждая функция, помеченная как inline в случае разрешенного инлайнинга, и каждая вообще вне зависимости от того, помечена как inline, или нет, в случае "встраивать все подходящие (Any suitable)", проверяется компилятором на соотвтествие некоторому условию. Если преимущество, достигнутое встраиванием кода, меньше некоторого порога, то функция не встраивается, сколько ты компилятор не проси.
Есть набор требований, которым должна удовлетворять функция, чтобы быть встроенной. К примеру, сколько не пиши inline возле функции с неопределенным количеством аргументов, компилятор ее не встроит (я о VC).
Вообще, есть MS-расширение по встроенным функциям — __forceinline. Поищи его в MSDN. На странице описания приводится полный перечень ситуаций, в которых функция НЕ может быть встроена (даже при указании _forceinline).
Так-что, уверенным в том, что функция встроилась, быть нельзя. Но для всяких обычных, без выкрутасов, аксессоров и т.д. это делается без проблем.
__forceinline — если не ошибаюсь, при его использовании как раз попрут ворнинги при невозможности встроить? Кстати борланд при невозможности втроить ругается.
Здравствуйте Fiend, Вы писали:
F>__forceinline — если не ошибаюсь, при его использовании как раз попрут ворнинги при невозможности встроить? Кстати борланд при невозможности втроить ругается.
Compiler Warning (level 1) C4714
'function' : function marked as __forceinline not inlined
The given function was selected for inline expansion, but the compiler did not perform the inlining.
Compiler Warning (level 4) C4710
'function' : function not inlined
The given function was selected for inline expansion, but the compiler did not perform the inlining.
Здравствуйте Fiend, Вы писали:
B>>Или в h-файл, или в в срр-файл (в этом случае не забыть добавить inline)
F>Извини, не понял. Ты советуешь сделать что-то типа такого?
F>//a.h F>class A{ F>public: F> void Some()const; F>};
F>//a.cpp F> inline void A::Some()const{}
F>Если да, то пробовал ли скомпилить/скомпоновать?
В общем случае это работать не будет. Где бы 'inline' функция не определялясь — внутри класса ли, снаружи класса ли — эта функция обязана быть явно определена во всех единициах компиляции, в которых она используется. По этой причине, если есть необходимость пользоваться 'inline' функцией из нескольких единиц компиляции, все равно придется включать ее определение #include-ом во все эти единицы компиляции.
Поместить определение 'inline' функции в *.cpp файл можно, но вызываться при этом она будет только из этого *.cpp файла. Что, разумеется, практически неприемлемо. Поэтому, если определение класса сидит в *.h файле, то и определения всех его 'inline' функций должны сидеть там же (или, может быть, в другом заголовочном файле, но не в файле реализации *.cpp).
?
АТ>В общем случае это работать не будет. Где бы 'inline' функция не определялясь — внутри класса ли, снаружи класса ли — эта функция обязана быть явно определена во всех единициах компиляции, в которых она используется. По этой причине, если есть необходимость пользоваться 'inline' функцией из нескольких единиц компиляции, все равно придется включать ее определение #include-ом во все эти единицы компиляции.
АТ>Поместить определение 'inline' функции в *.cpp файл можно, но вызываться при этом она будет только из этого *.cpp файла. Что, разумеется, практически неприемлемо. Поэтому, если определение класса сидит в *.h файле, то и определения всех его 'inline' функций должны сидеть там же (или, может быть, в другом заголовочном файле, но не в файле реализации *.cpp).
Полностью согласен. Но вернемся к нашему примеру: есть некая функция-член (приватная), которая вызывается только из других методов этого класса. В этом случае ее определение можно поместить в тот же cpp-файл, где определены все пользователи этой функции. Как правило, реализация всех методов класса содержится в одном cpp-файле, поэтому проблем быть не должно.
Конечно, если кто-то разбросает реализацию класса по нескольким файлам, то остается определять нашу функцию в хедере...
К чему весь этот огород?
Почему бы реализации всех функций (и маленьких, и больших) писать в .cpp (без всяких inline).
А если нужна скорость (в большинстве случаев так оно и есть), при компиляции включить -Ob2, если используется CL.
Здравствуйте, Dancer, Вы писали:
D>Ситуация такая: есть inline-функция — член класса. Она вызывается только из других функций-членов того же класса. Обязательно ли ее определение должно располагаться раньше всех вызовов, т.е. раньше определений всех остальных методов класса? Или может просто запихать ее в h-файл, если по-другому нельзя?
если реализация всех вызывателей лежит в одном cpp-файле, то лучше поместить определение этой функции в этот же файл.
Выгоды этого очевидны: если нужно изменить реализацию этой встроенной функции, то нужно будет только перекомпилировать этот файл и перелинковать программу, а если поместить реализацию в h-файл, то придется перекомпилировать все файлы, включающие этот хедер (хотя необходимости в этой реальной никакой не будет; это, конечно, можно учесть при написании make-файла, только мне искренне будет жаль того человека, который за это возьмется), потому что автоматом make просто сравнит время изменения файлов и придется идти обедать, пока все перекомпилируется.
D>И вообще, кому-нибудь достоверн известно, сильно подставляемые функции ускоряют работу?
известно, ускоряют, а если функция короткая и много раз вызывается, то сильно.