![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| 17dufa |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
Добрый день.
Собственно интересует такой вопрос - а почему на определенные в рамках класса функции не ругается линкер, что они already defined? это просто требование стандарта или такое определение чем-то концептуально отличается от определения просто функции? то есть вот такое линкуется
а вот такое нет
*ну и то же самое для
|
||||||
|
|||||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
насколько я помню, функции, реализованные внутри класса, считаются inline
если во втором случае ты перед функцией int f(int i) напишешь слово inline, то он тоже будет линковаться |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
Alek86, точно. никак не мог подумать, что inline влияет на линковку, хотя это закономерно, если с минуту поразмышлять.
|
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Alek86,
правильно помнишь.
|
||||
|
|||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Но компилятор (Microsoft) не будет ругаться, если в двух единицах трансляции определены две одноименные inline функции с одинаковым прототипом (declaration), но с разными реализациями (definition). У них же разные области видимости. Некорректности проявляются только на этапе выполнения такой программы. |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
1. То, что микрософт не ругается еще ни о чем не говорит. 2. Это не отменяет вышесказанного. |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Но все-таки inline-функции не обладают внешними связями и не могут непосредственно видеть друг друга (если определены в разных единицах трансляции), или я ошибаюсь?
Это сообщение отредактировал(а) FCM - 2.11.2009, 15:29 |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
инлайн функции ДОЛЖНЫ быть определены во всех единицах трансляции, в которых они используются и если функция со вшешним связыванием объявлена инлайн - она должна быть объявлена инлайн во всех единицах трансляции, в которых используется. А само ключевое слово инлайн на linkage функции никак не влияет. |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
azesmcar, "А само ключевое слово инлайн на linkage функции никак не влияет." Можно подробнее? Я, к сожалению, ни слова не понял.
|
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
FCM, ключевое слово "inline" - это всего лишь рекомендация компилятору и указание, что данная функция может быть определена в нескольких единицах трансляции. Т.е. если ты пометил функцию встраиваемой, это совсем не значит, что она будет встроена (особенно, в режиме отключенной оптимизации).
|
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
17dufa
про linkage http://www.cyberguru.ru/programming/cpp/cp...way-page25.html Добавлено через 1 минуту и 40 секунд
более того, даже если она будет встраиваемой в одном участке кода, это не значит что она встраиваемая всегда. Встраивается вызов функции. |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
azesmcar, несколько вопросов:
1. inline и внешнее/динамическое связывание - это как? 2. возвращаясь к первому вопросу, если компилятор положит на inline и таки сгенерит функцию, вернутся ошибки линковки или компилятор будет генерить функцию очень специальным образом? |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
В каком смысле? Обыкновенная функция со внешним связыванием, просто с ключевым словом inline. Я же говорю, инлайн с linkage никак не влияет.
нет, ошибок не будет http://forum.vingrad.ru/forum/topic-275681...tion/index.html последние 3 сообщения. Это сообщение отредактировал(а) azesmcar - 2.11.2009, 16:55 |
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
В этих последних 3-х сообщениях есть такие слова
"Однако при помощи inline можно влиять на способ компоновки." Это утверждение ошибочно ? И еще "инлайн функции не подчиняются ему (OneDefinitionRule)". Это так? |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
проще говоря, если компилятор видит inline функцию, то он обрабатывает ее обычным образом, плюс, в тех местах, где считает необходимым, он встраивает ее тело вместо вызова...
|
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Вот цитата с
http://msdn.microsoft.com/en-us/library/z8y1yy88(VS.71).aspx Functions that are declared as inline, and that are not class member functions, have internal linkage unless otherwise specified. Что же есть на самом деле? |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
имеется в виду, думаю, то что inline функции не члены классов не экспортируются из dll библиотек.
|
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
azesmcar, мое понимание все уменьшается и уменьшается. итак inline - это рекомендация компилятору. он имеет право на нее покласть и в целом обрабатывает inline функции обычным образом, хотя и старается по возможности встроить вызовы таких функций. тогда вопрос - почему нет ошибок линковки вида "already defined"? может все-таки не совсем обычным образом, какой-то флажок что ли ставит или еще чего такое незаметное делает, чтоб линкер с ума не сходил?
и возвращаясь в вопросу о dll. в этом объявлении
на inline будет положено в 100% случаев (мелкософт такое компилит даже без варнингов)? |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
потому что inline функция должна быть объявлена во всех единицах трансляции, в которых используется, вот она и объявлена, все соответствует стандарту, в чем проблема?
не знаю что там конкретно делает компилятор, флажок или что-то там другое, но ошибки он не должен выдавать. нет, с чего вдруг? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Вы рассматриваете вопрос односторонне : inline это не только рекомендация встраивания, а также указание способа компоновки функции, которое компилятор (а в последствии линкер) не могут проигнорировать. |
|||
|
||||
| xvr |
|
||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Уточнение для топикстартера - под 'обработкой обычным образом' понимается обработка с точки зрения синтаксиса и семантики языка С++. Оттранслированное тело функции (если компилятор такое создаст) будет помещено в объектный файл особым образом, что бы линкер не ругался на множественные определения таковых функций. Пример -
Компиляция
объектник
это оно и есть |
||||||||||
|
|||||||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
xvr
ну теперь я думаю вопросов поубавиться Это сообщение отредактировал(а) azesmcar - 3.11.2009, 12:42 |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
azesmcar,
а компилятор позволяет не inline функции не объявлять в единицах трансляции, где они используются? я имею в виду работу компилятора по билду аппликайшена, использующего подобную библиотеку. не будет же компилятор бегать по длл в поисках объектного кода и пытаться его встроить? xvr, полегчало. спасибо. Интересно какие правила использует линкер для устранения конфликта имен? |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
имелось ввиду "определять" а не "объявлять". Ну эта инлайн функция еще может быть использована внутри самой библиотеки, это раз, и во вторых встраивать бинарный код никто не запрещает, другое дело что вряд ли кто либо этим будет заниматься. |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
azesmcar, думаю известным мне компиляторам даже при сильном желании не удастся вытащить код из dll, так как эти самые dll указываются как параметры линкера, компилятору про них неизвестно. Но стандарт не запрещает написать компилятор, который тем не менее это сделает (и соответственно потребует доп параметров с указанием dll)?
Если в каждой единице трансляции будет определена inline функция, то я так понимаю для них будет использоваться статическое внутреннее связывание, и линкер по их поводу ваще не парится, то есть LINK_ONCE_DISCARD может как вариант приводить к тому, что подобные функции просто не будут включатся линкером в список имен. И далее рассуждая получаю, что статическое внешнее и динамические связывания для inline функций - это что-то из разряда юзанья их из lib и dll библиотек, то есть те самые случаи, когда слово inline по жизни не имеет эффекта (опустим тот факт, что оно могло оказать эффект при сборке этих lib, dll, меня в данный момент интересует аппликайшин, использующих эти библиотеки). |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
По поводу вставки inline на этапе линковки. Почти все современные компиляторы имеют режим трансляции, когда при трансляции отдельных модулей генерируется только промежуточное представление модуля, которое помещается в объектный файл вместо (а иногда и вместе) с кодом. На этапе линковки это представление извлекается из объектников (всех) и скармливается компилятору. При таком подходе компилятор имеет возможность заинлайнить все и везде
NB. Режим этот у всех называется по разному, и включается разными опциями. |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
xvr, класс. прям чую как умнею. главное не рехнуться
|
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
17dufa
Почитай Герба Саттера - More Exceptional C++, там подробно написано про inline. |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
azesmcar, как раз ищу его. после эйфории от первой части. наверно, стоит не мучаться, да распечатать то, что в электронном виде лежит.
|
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
17dufa, когда ты подключаешь хидер (с inline функцией) к исходникам приложения, то компилятор может встроить ее тело... А может и не встроить. В любом случае, он сгененирует "невстроенный" вариант этой функции. Затем, на этапе линковки, все не нужные экземпляры невстроенной функции будут заменены на ту, что предоставляет dll.
|
|||
|
||||
| FCM |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 461 Регистрация: 30.3.2009 Репутация: нет Всего: 9 |
Возвращаясь к вопросу о влиянии inline на linkage - все-таки дыма без огня не бывает- оказывается раньше влияло:
In the original C++ language, inline functions always had internal linkage. Then a change was made to allow the possibility of external linkage. Now a change has been made to make external linkage the default. This may alter the behavior of some existing code. |
|||
|
||||
| 17dufa |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 324 Регистрация: 2.3.2006 Репутация: 3 Всего: 5 |
bsa, ну в моем хидере может не быть определения функции, а только объявление
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |