Сообщение Re[11]: Откуда такая неизбывная приверженность к константам? от 23.10.2024 13:07
Изменено 23.10.2024 13:10 netch80
N>>В современных процессорах, как правило, деление на 0 или деление с переполнением не вызывает исключения
ЕМ>И это очень странно. Из каких соображений это делается?
We considered raising exceptions on integer divide by zero, with these exceptions causing a trap in most execution environments. However, this would be the only arithmetic trap in the standard ISA (floating-point exceptions set flags and write default values, but do not cause traps) and would require language implementors to interact with the execution environment’s trap handlers for this case. Further, where language standards mandate that a divide-by-zero exception must cause an immediate control flow change, only a single branch instruction needs to be added to each divide operation, and this branch instruction can be inserted after the divide and should normally be very predictably not taken, adding little runtime overhead.
The value of all bits set is returned for both unsigned and signed divide by zero to simplify the divider circuitry. The value of all 1s is both the natural value to return for unsigned divide, representing the largest unsigned number, and also the natural result for simple unsigned divider implementations. Signed division is often implemented using an unsigned division circuit and specifying the same overflow result simplifies the hardware.
N>>RISC-V обещает, что беззнаковое деление на 0 даст ~0 (как UINT_MAX).
ЕМ>Такой подход ломает одно из основных свойств целочисленного деления (модуль частного не больше модулей делимого и делителя).
Попытка деления на 0 вообще бессмысленна в пределах целых чисел. Что именно возвращать в таком легко детектируемом случае — вопрос реализации. См. выше.
N>>Язык может генерировать исключение на это или подставлять такой же безопасный дефолт.
ЕМ>В чем "безопасность" такого дефолта? Вот имеем байтовое смещение, делим на размер элемента, ожидаем получить индекс элемента. Вместо размера по ошибке делим на нуль, получаем UINT_MAX, применяем в качестве индекса. В соседней теме
Дата: 21.09 07:39
Сейчас тебе точно так же ни C ни C++ ничего не гарантируют. А должны были по умолчанию генерировать исключение, если по разуму, а не по комитету или кто там рулит. Так что тут без разницы. А вот возможность лёгкой проверки на такую ситуацию одной командой достаточна для устранения проблемы там, где она реально может быть.
N>>Если исключение отражается в видимой диагностике, это можно было бы написать.
N>>вообще подход, что не предполагается обрабатывать ошибки в арифметике, потому что нет возможности их отобразить в результате операции.
ЕМ>Почему нет? Или предусмотреть перехват возможного исключения, или проверить операнд(ы) перед выполнением операции.
Ну покажи это в современном языке. Я вот хочу видеть что-то в духе C# [tt]c = (checked)(a+b);/[tt] — контекстно и в самом языке. А вместо этого должен писать свои оболочки или использовать от какого-то странного вендора (Boost ещё лучший по свойствам, но API у этого модуля кошмарненький).
N>>Потом кто-то другой в другом месте перевёл запрос доступной памяти на использование вызова B-15E801, который способен отдать к нему дополнительно "DX = configured memory above 16M, in 64K blocks", соответственно до 4GB, а код в построителе таблиц для пейджинга просто не обновили соответственно.
ЕМ>А можно было просто иметь одну функцию вроде GetMemorySize, которая определяет объем памяти любым удобным образом, тогда и части кода согласовывать не придется.
Так она и была. И было установлено при написании кода VM, что она не даст значение выше 64MB.
(В рамках того же предполагаемого сценария)
N>>использовать тотальный defensive programming между собственными микро-компонентами в пределах одной службы... как по мне, это избыточно в 99.99% случаев, толку нет.
ЕМ>В ортогональности и унификации всегда есть толк.
См. выше.
N>>В современных процессорах, как правило, деление на 0 или деление с переполнением не вызывает исключения
ЕМ>И это очень странно. Из каких соображений это делается?
We considered raising exceptions on integer divide by zero, with these exceptions causing a trap in most execution environments. However, this would be the only arithmetic trap in the standard ISA (floating-point exceptions set flags and write default values, but do not cause traps) and would require language implementors to interact with the execution environment’s trap handlers for this case. Further, where language standards mandate that a divide-by-zero exception must cause an immediate control flow change, only a single branch instruction needs to be added to each divide operation, and this branch instruction can be inserted after the divide and should normally be very predictably not taken, adding little runtime overhead.
The value of all bits set is returned for both unsigned and signed divide by zero to simplify the divider circuitry. The value of all 1s is both the natural value to return for unsigned divide, representing the largest unsigned number, and also the natural result for simple unsigned divider implementations. Signed division is often implemented using an unsigned division circuit and specifying the same overflow result simplifies the hardware.
N>>RISC-V обещает, что беззнаковое деление на 0 даст ~0 (как UINT_MAX).
ЕМ>Такой подход ломает одно из основных свойств целочисленного деления (модуль частного не больше модулей делимого и делителя).
Попытка деления на 0 вообще бессмысленна в пределах целых чисел. Что именно возвращать в таком легко детектируемом случае — вопрос реализации. См. выше.
N>>Язык может генерировать исключение на это или подставлять такой же безопасный дефолт.
ЕМ>В чем "безопасность" такого дефолта? Вот имеем байтовое смещение, делим на размер элемента, ожидаем получить индекс элемента. Вместо размера по ошибке делим на нуль, получаем UINT_MAX, применяем в качестве индекса. В соседней теме
Дата: 21.09 07:39
Сейчас тебе точно так же ни C ни C++ ничего не гарантируют. А должны были по умолчанию генерировать исключение, если по разуму, а не по комитету или кто там рулит. Так что тут без разницы. А вот возможность лёгкой проверки на такую ситуацию одной командой достаточна для устранения проблемы там, где она реально может быть.
N>>Если исключение отражается в видимой диагностике, это можно было бы написать.
N>>вообще подход, что не предполагается обрабатывать ошибки в арифметике, потому что нет возможности их отобразить в результате операции.
ЕМ>Почему нет? Или предусмотреть перехват возможного исключения, или проверить операнд(ы) перед выполнением операции.
Ну покажи это в современном языке. Я вот хочу видеть что-то в духе C# c = (checked)(a+b); — контекстно и в самом языке. А вместо этого должен писать свои оболочки или использовать от какого-то странного вендора (Boost ещё лучший по свойствам, но API у этого модуля кошмарненький).
N>>Потом кто-то другой в другом месте перевёл запрос доступной памяти на использование вызова B-15E801, который способен отдать к нему дополнительно "DX = configured memory above 16M, in 64K blocks", соответственно до 4GB, а код в построителе таблиц для пейджинга просто не обновили соответственно.
ЕМ>А можно было просто иметь одну функцию вроде GetMemorySize, которая определяет объем памяти любым удобным образом, тогда и части кода согласовывать не придется.
Так она и была. И было установлено при написании кода VM, что она не даст значение выше 64MB.
(В рамках того же предполагаемого сценария)
N>>использовать тотальный defensive programming между собственными микро-компонентами в пределах одной службы... как по мне, это избыточно в 99.99% случаев, толку нет.
ЕМ>В ортогональности и унификации всегда есть толк.
См. выше.