История изменений
Исправление Egor_, (текущая версия) :
а товарищ утверждает, что рантайм проверки не бесплатны, и есть масса ситуаций, когда платить эту цену бессмысленно и даже вредно.
Назови уже хоть какую-нибудь.
из трёх нижеперечисленных пунктов ты можешь одновременно выбрать не более чем два:
- кроссплатформенность
- производительность
- отсутствие UB
простой пример: конвертация double
в int64
с задизабленными исключениями плавучки
что имеем в железе:
- x64 (инструкция cvttsd2si): если исходное значение
double
выходит на границы целого типа, то возвращается значение0x8000000000000000
- arm64 (инструкции fcvtzs, fcvtzu): если исходное значение
double
выходит на границы целого типа, то возвращается крайнее (мин/макс) значение из допустимого диапазона, наиболее близкое к исходному
поэтому когда ты пытаешься сконвертировать одной инструкцией процессора число -1.0
в тип uint64
, то на x64 ты получишь 0x8000000000000000
, а на arm64 - 0
если потребовать одновременно кроссплатформенность (на разных процессорах результат операции должен быть одним и тем же числом) и отсутствие UB (результат операции должен быть чётко определён и описан в документации), то придётся платить потерей производительности - на какой-то из архитектур операцию придётся реализовывать не одной инструкцией процессора, а несколькими
автор LuaJIT, когда писал расширение Lua 5.1 с 64-битными целыми числами, посмотрел на это безобразие и сказал: «от кроссплатформенности уйти не получится, производительностью жертвовать не хочу, поэтому вот вам UB, ну а чо, раз сишники терпят наличие UB в своём языке, то и вы терпите»
такова жизнь: написание компиляторов - это постоянный поиск компромиссов между несовместимыми целями, и перфекционистам здесь делать нечего
чудес не бывает: там, где сишники получают UB, раст просто расплачивается производительностью за комфорт
Исходная версия Egor_, :
а товарищ утверждает, что рантайм проверки не бесплатны, и есть масса ситуаций, когда платить эту цену бессмысленно и даже вредно.
Назови уже хоть какую-нибудь.
из трёх нижеперечисленных пунктов ты можешь одновременно выбрать не более чем два:
- кроссплатформенность
- производительность
- отсутствие UB
простой пример: конвертация double
в int64
с задизабленными исключениями плавучки
что имеем в железе:
- x64 (инструкция cvttsd2si): если исходное значение
double
выходит на границы целого типа, то возвращается значение0x8000000000000000
- arm64 (инструкции fcvtzs, fcvtzu): если исходное значение
double
выходит на границы целого типа, то возвращается крайнее (мин/макс) значение из допустимого диапазона, наиболее близкое к исходному
поэтому когда ты пытаешься сконвертировать одной инструкцией процессора число -1.0
в тип uint64
, то на x64 ты получишь 0x8000000000000000
, а на arm64 - 0
если потребовать одновременно кроссплатформенность (на разных процессорах результат операции должен быть одним и тем же числом) и отсутствие UB (результат операции должен быть чётко определён и описан в документации), то придётся платить потерей производительности - на какой-то из архитектур операцию придётся реализовывать не одной инструкцией процессора, а несколькими
автор LuaJIT, когда писал расширение Lua 5.1 с 64-битными целыми числами, посмотрел на это безобразие и сказал «от кроссплатформенности уйти не получится, производительностью жертвовать не хочу, поэтому вот вам UB, ну а чо, раз сишники терпят наличие UB в своём языке, то и вы терпите»
такова жизнь: написание компиляторов - это постоянный поиск компромиссов между несовместимыми целями, и перфекционистам здесь делать нечего
там, где сишники получают UB, раст просто расплачивается производительностью за комфорт