LINUX.ORG.RU

История изменений

Исправление lovesan, (текущая версия) :

Это не совсем «бага», и не какая-то ошибка, как некоторые недалекие дурачки тут думают. Это фича.

Дело в том, что в отличие от говноязыков, типа C#, или Си, и тому подобных, реализации Common Lisp отлавливают все аппаратые исключения операций с плавающей точкой, в том числе например операции с NaN. Классы condition(исключений CL), которые в этом случае сигнализируются, даже прописаны в стандарте CL, типа вот для операций с NaN: http://l1sp.org/cl/floating-point-invalid-operation

Говноязыки же, мало что не отлавливают, но часто вообще не могут работать со включенными аппаратными исключениями для флоатов. По первой ссылке кстати там первый же коммент описывает этот момент:

.NET runtime and libraries are not compatible with enabled floating point exceptions. If you need floating point exceptions enabled for your C/C++ library, you need to disable around them around the calls to .NET runtime.

Похожее говно может случиться, например если использовать какие-то сишные или плюсовые библиотеки для работы с графикой, где всякие андерфлоу-оверфлоу на каждом шагу. Т.е. они могут натурально отсегфолтиться, если лисп включит исключения для флоатов.

В примере с WPF на винде, кстати, overflow возникает при рендеринге. Если бы лисп не включал обработку аппаратных ошибок, дотнету и нижележащим сишным либам было бы пофигу, сколько у них там NaN вместо чисел, и какие еще там говна с флоатами случаются.

На линупсах ситуация осложняется тем, что в нем, вместо нормально сделанной и продуманной вещи типа виндового SEH, есть доисторическое кривое worse-is-better говно мамонта под названием «сигналы». Которые говно просто by design, и не предназначены для современных многопоточных приложений, тем более с несколькими рантаймами в одном процессе. И таким образом даже если ошибка возникает в треде .NET, где-то в бэкграунде, тот же например SBCL его все-равно отлавливают. Это не проблема SBCL, это проблема сигналов.

Решение проблемы, самое простое - это отрубить в лиспе аппаратные исключения флоатов, а именно те виды, которые вызывают проблемы. Все ведущие реализации CL это позволяют. Или же вообще использовать что-то типа _fpreset на винде чтобы уж точно выключить их все, в контексте треда, кроме тех что нужны тому же .NET (там деление на ноль, по-моему, отлавливается)

Исходная версия lovesan, :

Это не совсем «бага», и не какая-то ошибка, как некоторые недалекие дурачки тут думают. Это фича.

Дело в том, что в отличие от говноязыков, типа C#, или Си, и тому подобных, реализации Common Lisp отлавливают все аппаратые исключения операций с плавающей точкой, в том числе например операции с NaN. Классы condition(исключений CL), которые в этом случае сигнализируются, даже прописаны в стандарте CL, типа вот для операций с NaN: https://l1sp.org/cl/floating-point-invalid-operation

Говноязыки же, мало что не отлавливают, но часто вообще не могут работать со включенными аппаратными исключениями для флоатов. По первой ссылке кстати там первый же коммент описывает этот момент:

.NET runtime and libraries are not compatible with enabled floating point exceptions. If you need floating point exceptions enabled for your C/C++ library, you need to disable around them around the calls to .NET runtime.

Похожее говно может случиться, например если использовать какие-то сишные или плюсовые библиотеки для работы с графикой, где всякие андерфлоу-оверфлоу на каждом шагу. Т.е. они могут натурально отсегфолтиться, если лисп включит исключения для флоатов.

В примере с WPF на винде, кстати, overflow возникает при рендеринге. Если бы лисп не включал обработку аппаратных ошибок, дотнету и нижележащим сишным либам было бы пофигу, сколько у них там NaN вместо чисел, и какие еще там говна с флоатами случаются.

На линупсах ситуация осложняется тем, что в нем, вместо нормально сделанной и продуманной вещи типа виндового SEH, есть доисторическое кривое worse-is-better говно мамонта под названием «сигналы». Которые говно просто by design, и не предназначены для современных многопоточных приложений, тем более с несколькими рантаймами в одном процессе. И таким образом даже если ошибка возникает в треде .NET, где-то в бэкграунде, тот же например SBCL его все-равно отлавливают. Это не проблема SBCL, это проблема сигналов.

Решение проблемы, самое простое - это отрубить в лиспе аппаратные исключения флоатов, а именно те виды, которые вызывают проблемы. Все ведущие реализации CL это позволяют. Или же вообще использовать что-то типа _fpreset на винде чтобы уж точно выключить их все, в контексте треда, кроме тех что нужны тому же .NET (там деление на ноль, по-моему, отлавливается)