Re[7]: VC++: не работает packaging для независимых функций
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 29.10.21 23:08
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

W>>вместо получения неопределённого поведения


ЕМ>Я не делаю программу "в стандарте C++". Я делаю ее в соответствии с документацией на MS VC++. Поэтому соответствие стандарту меня сейчас совершенно не интересует.


Плохая практика (это я так, лишь бы что вставить )


W>>опции /Gy, /opt:icf являются по сути опциями оптимизации.


ЕМ>Это меня тоже не интересует. Интересует только одно: правильно ли я использую эти опции. Если Вы считаете, что я использую их неправильно — поясните, пожалуйста, в чем именно.


Раз не работает, то тут 50 на 50


W>>Они не превращают неправильную программу, в которой уже допущена ошибка, в правильную.


ЕМ>Программа, в которой объекты данных определены более, чем в одной единице трансляции, тоже считается неправильной с точки зрения стандарта C++. Однако ж эти опции таки превращают ее в правильную. Почему?


Документация тоже может врать. Такое бывает...

Более интересно, зачем ты поперёк стандарта пытаешься переть
Маньяк Робокряк колесит по городу
Re[9]: VC++: не работает packaging для независимых функций
От: watchmaker  
Дата: 29.10.21 23:21
Оценка: 5 (1)
Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ> Вот и интересно, почему он не сворачивает таким же образом одинаковые функции с одинаковыми именами.


Потому что для них это ему запрещено делать. Явно запрещено. Рядом с каждым таким именем лежит поле, в котором написан запрет (IMAGE_COMDAT_SELECT_NODUPLICATES).

Кончено же им можно управлять, и программистам на С++ предоставили удобную возможность снимать запрет прямо в исходнике.

Ты уже неоднократно упоминал, что тебе этот способ известен. Но для других читателей повторю: снимается запрет ключевым словом inline. Когда-то давно оно как-то влияло на встраивание функций, но в современных плюсах у этого ключевого слова по сути осталась единственная роль: снять этот флаг запрета (ну и пара количественных, но не качественных эффектов, вроде разрешения не генерировать код для неиспользуемых функций).
Re[9]: VC++: не работает packaging для независимых функций
От: cserg  
Дата: 30.10.21 00:01
Оценка: 17 (2)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Фишка в том, что эта же технология (COMDAT) используется и для других подобных вещей. Например, inline-функции (как члены, так и независимые), которые по факту не инлайнятся, точно так же кладутся в COMDAT, и имена у них одни и те же в каждой единице трансляции, но на них линкер не ругается, а сворачивает тихо.

У COMDAT кроме имени есть еще признак "selection kind", который определяет, что должен делать линкер при обнаружении дублирования имен. Для функций-членов и независимых inline-функций компилятор установит значение "any", т.е. линкер может выбрать любой COMDAT с таким же именем,

ЕМ>Вот и интересно, почему он не сворачивает таким же образом одинаковые функции с одинаковыми именами.

а для обычных функций компилятор установит значение "no duplicates", т.е. линкер должен ругаться если обнаружит дублирование имен COMDAT. Используя dumpbin /SYMBOLS можно посмотреть значение "selection kind" для COMDAT.

ЕМ>Она действует на все сразу. Я ж не хочу подавлять ошибки, вызванные ошибочным определением разных функций с одинаковыми именами.

Ну, значит вам нужен __declspec(selectany) для функций или его аналог, а лучше __declspec(exactmatch). Хз почему ms не сделали.
Отредактировано 30.10.2021 0:13 cserg . Предыдущая версия .
Re[8]: VC++: не работает packaging для независимых функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.21 08:02
Оценка:
Здравствуйте, Marty, Вы писали:

M>Более интересно, зачем ты поперёк стандарта пытаешься переть


Хотя бы потому, что вероятность использования для этих проектов других компиляторов, кроме MS VC++, чуть менее, чем нулевая.
Re[10]: VC++: не работает packaging для независимых функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.21 08:20
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Потому что для них это ему запрещено делать. Явно запрещено. Рядом с каждым таким именем лежит поле, в котором написан запрет (IMAGE_COMDAT_SELECT_NODUPLICATES).


О, спасибо. Я что-то такое подозревал, но нагуглить никак не получалось.

W>Ты уже неоднократно упоминал, что тебе этот способ известен. Но для других читателей повторю: снимается запрет ключевым словом inline.


Это не способ, а костыль — с его помощью нельзя надежно управлять размещением функции, чтоб никогда не инлайнилась, а только вызывалась. Или извращению "__declspec (noinline) inline" можно доверять?
Re[10]: VC++: не работает packaging для независимых функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.21 08:26
Оценка:
Здравствуйте, cserg, Вы писали:

C>значит вам нужен __declspec(selectany) для функций или его аналог, а лучше __declspec(exactmatch). Хз почему ms не сделали.


Они многих простых и очевидных вещей не сделали, которым им самим сильно облегчили бы жизнь. Почему — хз...
Re[11]: VC++: не работает packaging для независимых функций
От: cserg  
Дата: 30.10.21 10:07
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>... Или извращению "__declspec (noinline) inline" можно доверять?

Нельзя, проверил у себя. Встраивает простую независимую функцию в релизном режиме. Да и в документации говорится, что __declspec(noinline) используется для функций-членов.
Re[9]: VC++: не работает packaging для независимых функций
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.10.21 12:04
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

M>>Более интересно, зачем ты поперёк стандарта пытаешься переть


ЕМ>Хотя бы потому, что вероятность использования для этих проектов других компиляторов, кроме MS VC++, чуть менее, чем нулевая.


Это оправдание для использования каких-то фич MSVC, если бы они были бы нужны. Но в данном случае всё делается языковыми штатными средствами
Маньяк Робокряк колесит по городу
Re[10]: VC++: не работает packaging для независимых функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.21 17:02
Оценка:
Здравствуйте, Marty, Вы писали:

M>в данном случае всё делается языковыми штатными средствами


Какими штатными языковыми средствами я могу определить в общем заголовке функцию, чтобы она гарантированно не инлайнилась, а была размещена отдельным кодом, но в единственном экземпляре?
Re[11]: VC++: не работает packaging для независимых функций
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.10.21 17:34
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

M>>в данном случае всё делается языковыми штатными средствами


ЕМ>Какими штатными языковыми средствами я могу определить в общем заголовке функцию, чтобы она гарантированно не инлайнилась, а была размещена отдельным кодом, но в единственном экземпляре?



Вооот, ты уже понемногу начал рассказывать о проблеме, которую пытаешься решить, а не о своём решении, которое у тебя не получается. Можно ещё немного поподробнее?


Как вариант решения — class/struct с operator(). Для оператора можно попробовать __declspec(noinline). Кстати, макросами можно сделать совместимо с GCC — __attribute__((noinline))

Имхо, это гораздо более предсказуемо, чем игрища с ключами компилятора/линкера, которые могут поломаться с большей вероятностью.


Хотя, operator() нельзя сделать сделать static'ом, чтобы вызывать без создания экземпляра объекта. Ну и синтаксис такого вызова не очень понятен — MyCoolStruct::operator()( actual args ), разве что.

Можно сделать через создание временного объекта и завернуть в макрос:

#define my_cool_noinline_function(...) MyCoolStruct().operator(__VA_ARGS__)


Или можно создавать в хидере static экземпляр, тогда можно и без макросов, и все фишки namespace'ов не потеряются.

В любом случае, я бы сначала поискал решения в рамках языка, и, возможно, его нестандартных расширений, чем через опции командной строки компилятора/линкера. Это, имхо, более надёжно. Ну и ещё можно посмотреть в сторону _Pragma, или как оно там, в новых стандартах, может там что-то есть
Маньяк Робокряк колесит по городу
Re[12]: VC++: не работает packaging для независимых функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 30.10.21 17:45
Оценка:
Здравствуйте, Marty, Вы писали:

M>ты уже понемногу начал рассказывать о проблеме, которую пытаешься решить


Я о ней упоминал
Автор: Евгений Музыченко
Дата: 27.10.21
еще три дня назад. Это ни разу не проблема, просто хотелось сделать легко, быстро и изящно, как в случае с подобными же общими данными.

M>Как вариант решения — class/struct с operator(). Для оператора можно попробовать __declspec(noinline).


Это уже не "штатные языковые средства", а "фичи MS VC++".

M>Можно сделать через создание временного объекта и завернуть в макрос:


Вот именно — костыли множатся и множатся... Проще тупо заинлайнить, и хрен с ними. Может, когда-нибудь потом вынесу в библиотеку, если накопится достаточно вариантов использования.
Re[13]: VC++: не работает packaging для независимых функций
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 30.10.21 18:24
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

M>>ты уже понемногу начал рассказывать о проблеме, которую пытаешься решить


ЕМ>Я о ней упоминал
Автор: Евгений Музыченко
Дата: 27.10.21
еще три дня назад. Это ни разу не проблема, просто хотелось сделать легко, быстро и изящно, как в случае с подобными же общими данными.


Я это видел. Но там тоже не описание проблемы, а твоё её решение.

И в чем проблема заинлайнить, а не добиваться того, чего ты пытаешься добиться?

Про общие данные тоже не очень понял, чем там лучше? extern решает? Так этот extern — грабель ещё тот, такого можно накостылять...



M>>Как вариант решения — class/struct с operator(). Для оператора можно попробовать __declspec(noinline).


ЕМ>Это уже не "штатные языковые средства", а "фичи MS VC++".


У GCC есть аналогичная фича. У других компилеров — скорее всего тоже. И вот у нас уже есть хоть и нештатное, но совместимое со всеми компиляторами решение. А не опасное дрочево с опциями командной строки.


M>>Можно сделать через создание временного объекта и завернуть в макрос:


ЕМ>Вот именно — костыли множатся и множатся... Проще тупо заинлайнить, и хрен с ними. Может, когда-нибудь потом вынесу в библиотеку, если накопится достаточно вариантов использования.


Не любишь костыли — rust тебе в руку

ЗЫ Я так и не понял, а что сразу мешало заинлайнить, зачем ты полез в залупу с изучением опций командной строки и тем, как и что помечается в объектниках?
Маньяк Робокряк колесит по городу
Re[14]: VC++: не работает packaging для независимых функций
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 31.10.21 08:57
Оценка:
Здравствуйте, Marty, Вы писали:

M>И в чем проблема заинлайнить, а не добиваться того, чего ты пытаешься добиться?


Просто раздражает, что возможность есть, а толком использовать ее нельзя.

M>Про общие данные тоже не очень понял, чем там лучше? extern решает?


Там в основном решает selectany. Объединение одинаковых строк, кстати, работает по тому же принципу, и GUID'ы размещаются так же.

M>ЗЫ Я так и не понял, а что сразу мешало заинлайнить, зачем ты полез в залупу с изучением опций командной строки и тем, как и что помечается в объектниках?


Так я давно знаю об этих опциях и использовании COMDAT, разве что во флагах IMAGE_COMDAT_SELECT_* не разбирался.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.