Здравствуйте, Евгений Музыченко, Вы писали:
W>>вместо получения неопределённого поведения
ЕМ>Я не делаю программу "в стандарте C++". Я делаю ее в соответствии с документацией на MS VC++. Поэтому соответствие стандарту меня сейчас совершенно не интересует.
Плохая практика (это я так, лишь бы что вставить )
W>>опции /Gy, /opt:icf являются по сути опциями оптимизации.
ЕМ>Это меня тоже не интересует. Интересует только одно: правильно ли я использую эти опции. Если Вы считаете, что я использую их неправильно — поясните, пожалуйста, в чем именно.
Раз не работает, то тут 50 на 50
W>>Они не превращают неправильную программу, в которой уже допущена ошибка, в правильную.
ЕМ>Программа, в которой объекты данных определены более, чем в одной единице трансляции, тоже считается неправильной с точки зрения стандарта C++. Однако ж эти опции таки превращают ее в правильную. Почему?
Документация тоже может врать. Такое бывает...
Более интересно, зачем ты поперёк стандарта пытаешься переть
ЕМ> Вот и интересно, почему он не сворачивает таким же образом одинаковые функции с одинаковыми именами.
Потому что для них это ему запрещено делать. Явно запрещено. Рядом с каждым таким именем лежит поле, в котором написан запрет (IMAGE_COMDAT_SELECT_NODUPLICATES).
Кончено же им можно управлять, и программистам на С++ предоставили удобную возможность снимать запрет прямо в исходнике.
Ты уже неоднократно упоминал, что тебе этот способ известен. Но для других читателей повторю: снимается запрет ключевым словом inline. Когда-то давно оно как-то влияло на встраивание функций, но в современных плюсах у этого ключевого слова по сути осталась единственная роль: снять этот флаг запрета (ну и пара количественных, но не качественных эффектов, вроде разрешения не генерировать код для неиспользуемых функций).
Re[9]: VC++: не работает packaging для независимых функций
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Фишка в том, что эта же технология (COMDAT) используется и для других подобных вещей. Например, inline-функции (как члены, так и независимые), которые по факту не инлайнятся, точно так же кладутся в COMDAT, и имена у них одни и те же в каждой единице трансляции, но на них линкер не ругается, а сворачивает тихо.
У COMDAT кроме имени есть еще признак "selection kind", который определяет, что должен делать линкер при обнаружении дублирования имен. Для функций-членов и независимых inline-функций компилятор установит значение "any", т.е. линкер может выбрать любой COMDAT с таким же именем,
ЕМ>Вот и интересно, почему он не сворачивает таким же образом одинаковые функции с одинаковыми именами.
а для обычных функций компилятор установит значение "no duplicates", т.е. линкер должен ругаться если обнаружит дублирование имен COMDAT. Используя dumpbin /SYMBOLS можно посмотреть значение "selection kind" для COMDAT.
ЕМ>Она действует на все сразу. Я ж не хочу подавлять ошибки, вызванные ошибочным определением разных функций с одинаковыми именами.
Ну, значит вам нужен __declspec(selectany) для функций или его аналог, а лучше __declspec(exactmatch). Хз почему ms не сделали.
Здравствуйте, watchmaker, Вы писали:
W>Потому что для них это ему запрещено делать. Явно запрещено. Рядом с каждым таким именем лежит поле, в котором написан запрет (IMAGE_COMDAT_SELECT_NODUPLICATES).
О, спасибо. Я что-то такое подозревал, но нагуглить никак не получалось.
W>Ты уже неоднократно упоминал, что тебе этот способ известен. Но для других читателей повторю: снимается запрет ключевым словом inline.
Это не способ, а костыль — с его помощью нельзя надежно управлять размещением функции, чтоб никогда не инлайнилась, а только вызывалась. Или извращению "__declspec (noinline) inline" можно доверять?
Re[10]: VC++: не работает packaging для независимых функций
Здравствуйте, cserg, Вы писали:
C>значит вам нужен __declspec(selectany) для функций или его аналог, а лучше __declspec(exactmatch). Хз почему ms не сделали.
Они многих простых и очевидных вещей не сделали, которым им самим сильно облегчили бы жизнь. Почему — хз...
Re[11]: VC++: не работает packaging для независимых функций
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>... Или извращению "__declspec (noinline) inline" можно доверять?
Нельзя, проверил у себя. Встраивает простую независимую функцию в релизном режиме. Да и в документации говорится, что __declspec(noinline) используется для функций-членов.
Re[9]: VC++: не работает packaging для независимых функций
Здравствуйте, Евгений Музыченко, Вы писали:
M>>Более интересно, зачем ты поперёк стандарта пытаешься переть
ЕМ>Хотя бы потому, что вероятность использования для этих проектов других компиляторов, кроме MS VC++, чуть менее, чем нулевая.
Это оправдание для использования каких-то фич MSVC, если бы они были бы нужны. Но в данном случае всё делается языковыми штатными средствами
Здравствуйте, Marty, Вы писали:
M>в данном случае всё делается языковыми штатными средствами
Какими штатными языковыми средствами я могу определить в общем заголовке функцию, чтобы она гарантированно не инлайнилась, а была размещена отдельным кодом, но в единственном экземпляре?
Re[11]: VC++: не работает packaging для независимых функций
Здравствуйте, Евгений Музыченко, Вы писали:
M>>в данном случае всё делается языковыми штатными средствами
ЕМ>Какими штатными языковыми средствами я могу определить в общем заголовке функцию, чтобы она гарантированно не инлайнилась, а была размещена отдельным кодом, но в единственном экземпляре?
Вооот, ты уже понемногу начал рассказывать о проблеме, которую пытаешься решить, а не о своём решении, которое у тебя не получается. Можно ещё немного поподробнее?
Как вариант решения — class/struct с operator(). Для оператора можно попробовать __declspec(noinline). Кстати, макросами можно сделать совместимо с GCC — __attribute__((noinline))
Имхо, это гораздо более предсказуемо, чем игрища с ключами компилятора/линкера, которые могут поломаться с большей вероятностью.
Хотя, operator() нельзя сделать сделать static'ом, чтобы вызывать без создания экземпляра объекта. Ну и синтаксис такого вызова не очень понятен — MyCoolStruct::operator()( actual args ), разве что.
Можно сделать через создание временного объекта и завернуть в макрос:
Или можно создавать в хидере static экземпляр, тогда можно и без макросов, и все фишки namespace'ов не потеряются.
В любом случае, я бы сначала поискал решения в рамках языка, и, возможно, его нестандартных расширений, чем через опции командной строки компилятора/линкера. Это, имхо, более надёжно. Ну и ещё можно посмотреть в сторону _Pragma, или как оно там, в новых стандартах, может там что-то есть
еще три дня назад. Это ни разу не проблема, просто хотелось сделать легко, быстро и изящно, как в случае с подобными же общими данными.
M>Как вариант решения — class/struct с operator(). Для оператора можно попробовать __declspec(noinline).
Это уже не "штатные языковые средства", а "фичи MS VC++".
M>Можно сделать через создание временного объекта и завернуть в макрос:
Вот именно — костыли множатся и множатся... Проще тупо заинлайнить, и хрен с ними. Может, когда-нибудь потом вынесу в библиотеку, если накопится достаточно вариантов использования.
Re[13]: VC++: не работает packaging для независимых функций
еще три дня назад. Это ни разу не проблема, просто хотелось сделать легко, быстро и изящно, как в случае с подобными же общими данными.
Я это видел. Но там тоже не описание проблемы, а твоё её решение.
И в чем проблема заинлайнить, а не добиваться того, чего ты пытаешься добиться?
Про общие данные тоже не очень понял, чем там лучше? extern решает? Так этот extern — грабель ещё тот, такого можно накостылять...
M>>Как вариант решения — class/struct с operator(). Для оператора можно попробовать __declspec(noinline).
ЕМ>Это уже не "штатные языковые средства", а "фичи MS VC++".
У GCC есть аналогичная фича. У других компилеров — скорее всего тоже. И вот у нас уже есть хоть и нештатное, но совместимое со всеми компиляторами решение. А не опасное дрочево с опциями командной строки.
M>>Можно сделать через создание временного объекта и завернуть в макрос:
ЕМ>Вот именно — костыли множатся и множатся... Проще тупо заинлайнить, и хрен с ними. Может, когда-нибудь потом вынесу в библиотеку, если накопится достаточно вариантов использования.
Не любишь костыли — rust тебе в руку
ЗЫ Я так и не понял, а что сразу мешало заинлайнить, зачем ты полез в залупу с изучением опций командной строки и тем, как и что помечается в объектниках?
Здравствуйте, Marty, Вы писали:
M>И в чем проблема заинлайнить, а не добиваться того, чего ты пытаешься добиться?
Просто раздражает, что возможность есть, а толком использовать ее нельзя.
M>Про общие данные тоже не очень понял, чем там лучше? extern решает?
Там в основном решает selectany. Объединение одинаковых строк, кстати, работает по тому же принципу, и GUID'ы размещаются так же.
M>ЗЫ Я так и не понял, а что сразу мешало заинлайнить, зачем ты полез в залупу с изучением опций командной строки и тем, как и что помечается в объектниках?
Так я давно знаю об этих опциях и использовании COMDAT, разве что во флагах IMAGE_COMDAT_SELECT_* не разбирался.