cppasm Извини братан, не понял. ^) Только для чего нужно уметь это обрабатывать? По-моему нормальный компилятор, на дефолтовых настройках, должен предвидеть подобную коллизию.
Каким образом? Юзаем либу, там есть функция Encode(), и у нас в коде тоже есть такая функций. Линкер ругнется на то, что 2 функции с одинаковыми именами. Всё верно.
cppasm Если я не ошибаюсь, то не важно, заинлайнит он функцию или нет. Сам кейворд inline подскажет линкеру, что это функция, пытающаяся быть inline, и для нее нужно использовать иные методы связывания имен. То есть линкер в курсе и ругаться не будет. Если я не ошибаюсь Попробуй.
_DEN_ По-моему даже не обязательно юзать inline, на дефолтных настройках для таких функций это подразумевается.
Ты так ничего и не понял... Заголовочный файл подключается во многие *.с, и соответственно функция будет в каждом из них. Линкеру потом на картах таро выкинуть какую из них использовать? Не писал быть хоть ерунды... Что подразумевается? Есть три объектника: obj1.obj, obj2.obj, obj3.obj В первом есть доступная из вне функция my_func, во втором есть доступная из вне функция my_func (имя одинаковое). А третий использует внешнюю функцию my_func (extern). Вопрос - из какого модуля линкер должен взять эту функцию, obj1 или obj2? Ему монетку бросить? Да я уже попробовал. Не ругается. Кстати что интересно - функция эта наружу видна из всех объектников. И если в другом модуле её использовать как extern - она используется нормально. Просто компилятор помечает для линкера что возможно несколько реализаций, и линкер не ругается.
cppasm >Заголовочный файл подключается во многие *.с, и соответственно функция будет в каждом из них. Конечно, мне это не дано. >Линкеру потом на картах таро выкинуть какую из них использовать? На это ограничений не накладывается. n0name Меняет то, что такие функции могут инлайнится компилятором.
inline по сути - это дополнительный уровень разграничения между ф-циями, которые компилятор может заинлайнить, и теми, инлайн которых запрещён. Т.е. компилятору можно запретить инлайн: 1. всех ф-ций (/Ob0) 2. не inline ф-ций (/Ob1). 3. никаких ф-ций (т.е. всё разрешить) (/Ob2). Единственным определённым следствием этого атрибута есть помещение ф-ции в COMDAT-сегмент, что позволяет иметь несколько определений этой ф-ции в разных obj. С этой точки зрения inline - это вроде __declspec(selectany) для данных.
green - спасибо. Действительно так и есть. Резюме: Если функция инлайнится - она встаивается в код и тут всё ясно. Если же нет - в каждом модуле функция помещается в COMDAT сегмент, и при сборке линкер выбирает лишь один из них, остальные игнорирует (выбрасывает).
cppasm Линкер может оставлять несколько определений inline-ф-ции, если она определена в нескольких obj и там же вызывается как ф-ция. Т.е. приоритет отдаётся реализации ф-ции из своего obj.
Ну это зависит от атрибутов сегмента COMDAT. Там есть варианты: выбирать любой, выбирать любой если содержимое одинаково, выбирать из своего файла, выбирать с бо'льшим размером. На практике я проверил - студия выбирает первый попавшийся, остальные выбрасывает. Кстати вопрос немного не в тему. У Intel C++ есть ключ для межфайлового инлайна (/Qipo). Т.е. он в состоянии инлайнить функции, реализованные в другом файле. По сути он из всех исходников склеивает один большой, и потом уже оптимизирует. А у Visual Studio есть что-нибудь подобное? На текущий момент у меня сделано просто:
cppasm Да, ты прав. Однако, странно... Получается, что логика работы программы зависит от опций компиляции - логически идентичные вызовы ф-ции работают по-разному. Особо весёлый случай будет, если ф-ция частично заинлайнилась, а частично вызывается в пределах одного модуля. Интересно, что по этому поводу говорит Стандарт С++. --- А вот что говорит: Код (Text): An inline function shall be defined in every translation unit in which it is used and [u]shall have exactly the same definition in every case[/u] Значит всё ок, студия имеет право брать первое попавшееся определение. --- Да. /GL (compiler) + /LTCG (linker).
Ещё заметил, что GDI+ заголовки помимо переходников к dll содержат и функции с кодом, которые не инлайнятся даже при /LTCG (видны в exe и olly по ctrl+F5 открывает соответсвующий .h), например, inline Image* Image::Clone. И никакой ругани при компиляции не наблюдается, хотя GdiPlus.h есно включён в кучу модулей.
Ну у неё же указан inline. Как уже выяснили - независимо от того встраивается функция объявленная как inline, или так и остаётся функцией, можно иметь несколько вариантов этой функции в объектниках. Линкер на это ругаться не будет - просто выберет первую попавшуюся, остальные выкинет. При этом в стандарте написано что реализации у всех дубликатов должны быть одинаковы. Это забота программиста. А насчёт того что код не встраивается с /LTCG - я тут потестировал. Она реально работает, т.е. код из других модулей инлайнит. Просто в студии критерии инлайна пересмотрели, и решает инлайнить она достаточно не часто. По крайней мере VC++ 6.0 SP6 Pro у меня гораздо агрессивнее инлайнит чем VS 2008 Express. А указать критерии инлайна (максимальный размер) ключами нельзя в отличии к примеру от Intel C++.