Здравствуйте, пффф, Вы писали:
П>В принципе, можно сделать два разных хидера, содержащие inline функцию с одним именем, но разным определением, включить их в разные ЕТР, и слинковать в один исполняемый файл. П>Но это пример не менее искуственный, чем определение inline функции содержащее ifdef'ы, используемое в разных ЕТР, компилируемых с разным набором define'ов, и собираемые в один исполняемый файл
Вот именно.
Люди километрами используют inline код (один буст чего стоит) и ничего не ломается. Почему? Потому что правильная декомпозиция, использование пространств имен и здравого смысла.
А с дуру можно и х. сломать.
Re[15]: Исследование __attribute__((always_inline)) / __forc
П>В принципе, можно сделать два разных хидера, содержащие inline функцию с одним именем, но разным определением, включить их в разные ЕТР, и слинковать в один исполняемый файл.
Да, совершенно верно, я именно такую возможность и предполагал.
П>Но это пример не менее искуственный, чем определение inline функции содержащее ifdef'ы, используемое в разных ЕТР, компилируемых с разным набором define'ов, и собираемые в один исполняемый файл
С какой-то стороны пример конечно искуственный, но неужели не видно принципиальной разницы? ifdef-ы и define-ы и предназначены для того чтобы менять компилируемый код. То есть если я компилирую код с другими дефайнами, я явно говорю компилятору, что это уже немного другой код. Если же я просто меняю уровень оптимизации или файлы местами, я все-таки не ожидаю изменения функционала.
Вообще я так понимаю проблема в том, что по каким-то причинам в популярной литературе совершенно неверно описывается функциональность inline. Говорится о встраивании, и всяких там рекомендациях компилятору. Реальная же функциональность заключается в следующем:
Объявление функции с ключевым словом inline говорит линкеру о том, что надо забить на проверку сушествования функций с одинаковым названием в разных модулях. И если программист это допустил, сам виноват, то, какая функция будет вызвана — это UB.
Вот и вся функциональность, почему ее прячут в дебрях стандарта не понятно.
Re[16]: Исследование __attribute__((always_inline)) / __forc
K>С какой-то стороны пример конечно искуственный, но неужели не видно принципиальной разницы? ifdef-ы и define-ы и предназначены для того чтобы менять компилируемый код. То есть если я компилирую код с другими дефайнами, я явно говорю компилятору, что это уже немного другой код.
Ты разным копиям компилятора говоришь, что это разный код. А потом собираешь это в один исполняемый файл.
K>Если же я просто меняю уровень оптимизации или файлы местами, я все-таки не ожидаю изменения функционала.
Ну, если ты напрягся, и написал одинаковые inline функции в разных ЕТР, то странно, что ты не ожидаешь изменения функционала. Ведь зачем-то ты это делал?
Принципиальной разницы нет, и то и другое — явно изъявляемое желание походить по граблям.
И лично я не вижу ни одной причины, по которой приходилось бы делать inline функции в сипипишнике
K>Вообще я так понимаю проблема в том, что по каким-то причинам в популярной литературе совершенно неверно описывается функциональность inline. Говорится о встраивании, и всяких там рекомендациях компилятору. Реальная же функциональность заключается в следующем:
K>Объявление функции с ключевым словом inline говорит линкеру о том, что надо забить на проверку сушествования функций с одинаковым названием в разных модулях. И если программист это допустил, сам виноват, то, какая функция будет вызвана — это UB.
Да вроде и об этом пишут. Впрочем, я популярную литературу сто лет не читал, не в курсе, что там пишут. В любом случае, это претензии к авторам этой литературы
K>Вот и вся функциональность, почему ее прячут в дебрях стандарта не понятно.
А где оно должно быть? На первой странице? В стандарте много чего есть для первой страницы. А лучше всего весь стандарт на первой странице разместить, чтобы сразу всё было видно
Re[13]: Исследование __attribute__((always_inline)) / __forc
Здравствуйте, пффф, Вы писали:
П>Дико раздувался он лет 20 назад, сейчас компиляторы поумнели.
Поумнели они в основном там, где программисту не дали возможности ни оптимизировать вручную, ни подсказать компилятору способы это сделать.
Тупой пример: определите шаблонную функцию, принимающую пару указателей произвольного типа (хоть одного, хоть разных). В самом начале функции определите переменные, получающие результат преобразования указателей в числовой тип (int, uint64_t и т.п.). Пусть она вернет, например, сумму или разность этих значений.
Определите несколько функций, вызывающих этот шаблон с объектами разных типов (хоть с указателями на char, int, long и т.п.). Скомпилируйте с оптимизацией и посмотрите код — компилятор, скорее всего, вставит формулу непосредственно, ибо делать вызов будет дороже.
Теперь усложняйте формулу произвольным образом. Очень скоро компилятор перестанет вставлять код и будет только делать вызовы. Но на каждую пару типов он будет генерить отдельный экземпляр шаблона, хотя там вообще нет ни байта кода, специфичного для типов — он весь одинаковый. Режимами оптимизации попробуйте добиться, чтобы компилятор выносил общий код. У меня с VC++ и GCC не получилось.
И это предельно тупой, очевидный случай. А замените формулу вызовами других шаблонных функций, которые что-то делают с указателями, не обращая внимания на типы (например, добавляют в массивы или списки, принимают решения по "больше/меньше" и т.п.), и визуальная очевидность пропадет — с виду будет казаться, что идет какая-то серьезная работа, зависящая от типа. Таких лишних экземпляров в большой программе может быть довольно много.
И типичный современный программист, наученный вот этими сказками "компилятор умнее тебя, он сам разберется", над этим вообще не задумывается. Вся "умность" компилятора в таком случае сведется к генерации рабоспособного кода, а с раздуванием он ничего не сделает. При типовом профилировании этого тоже не видно. Так и будут списывать раздувание на разные причины, если не займутся анализом структуры генерируемого кода.
П>И если ты руками напишешь перегрузки для всех нужных типов — у тебя код тоже раздуется, причем даже побольше, чем в случае использования шаблонов.
В вышеописанном случае код получится примерно одинаковым.
Re[17]: Исследование __attribute__((always_inline)) / __forc
Здравствуйте, пффф, Вы писали:
П>Ты разным копиям компилятора говоришь, что это разный код. А потом собираешь это в один исполняемый файл.
ну, вот опять нужны разные копии компилятора и какие-то явные ухишрения чтоб это сделать. Тут просто случайно получается конфликт имен, который отследить практически невозможно.
П>Ну, если ты напрягся, и написал одинаковые inline функции в разных ЕТР, то странно, что ты не ожидаешь изменения функционала. Ведь зачем-то ты это делал?
Ясное дело, надо писать все правильно. Но не надо доказывать, что возможность просто взять и так сделать это серьезные грабли.
П>Принципиальной разницы нет, и то и другое — явно изъявляемое желание походить по граблям.
Нет, лично у меня скорей желание не попасть на грабли в большом количестве старого кода. А для этого надо как минимум знать, что это грабли, а это почему-то скрывают.
П>И лично я не вижу ни одной причины, по которой приходилось бы делать inline функции в сипипишнике
Потому, что традиционно считают что это оптимизация, и это рекомендует компилятору обратить на функцию внимание и попытаться встроить ее. Если ты покажешь мне где-нибудь информацию, где просто пишут что не надо объявлять инлайн в срр буду тебе признателен.
K>>Вообще я так понимаю проблема в том, что по каким-то причинам в популярной литературе совершенно неверно описывается функциональность inline. Говорится о встраивании, и всяких там рекомендациях компилятору. Реальная же функциональность заключается в следующем:
K>>Объявление функции с ключевым словом inline говорит линкеру о том, что надо забить на проверку сушествования функций с одинаковым названием в разных модулях. И если программист это допустил, сам виноват, то, какая функция будет вызвана — это UB.
П>Да вроде и об этом пишут. Впрочем, я популярную литературу сто лет не читал, не в курсе, что там пишут. В любом случае, это претензии к авторам этой литературы
Где? Да у меня претензии, что об этих граблях как-то принято помалкивать. Причем все кому ни лень пишут про бесполезную хрень "рекомендацию компилятору" и что-то в этом духе...
K>>Вот и вся функциональность, почему ее прячут в дебрях стандарта не понятно.
П>А где оно должно быть? На первой странице? В стандарте много чего есть для первой страницы. А лучше всего весь стандарт на первой странице разместить, чтобы сразу всё было видно
Я читал твое предыдущее сообщение, ты вообще ничего не понял, и придумал какие-то ifdef. Ты точно так же как и я не знал об этих граблях, а сейчас чего-то хочешь мне доказать.
Re[4]: Исследование __attribute__((always_inline)) / __force_inline
Здравствуйте, ksandro, Вы писали:
K>вместо того, чтобы задеприкейтить инлайн
Подобные решения фактически двигают C++ в сторону "просто еще одного языка", лишая его уникальных свойств, которые и привели к его оглушительному успеху.
Возможно, это закономерно. "Революции пожирают сами себя".
K>на это ключевое слово решили навесить новой функциональности...
А вот это верно. Стремление экономить ключевые слова любой ценой тоже до добра не доведет.
Re[5]: Исследование __attribute__((always_inline)) / __force_inline
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>А вот это верно. Стремление экономить ключевые слова любой ценой тоже до добра не доведет.
Но ведь применительно к inline эта функциональность всегда была. Она была обусловлена технической потребностью избежать ODR violation.
Единственное что сделали в последющих редакциях языка — это сместили фокус с "inline-просьба встроить вызов" на "inline-способ избежать ODR-violation для определений в header".
Произошла смена фокуса инструмента с его видимой части, на его техническую часть. Однако эта техническая часть всегда была при нем, иначе бы оно просто не работало как нужно.