Начиная с Delphi 1 RTL использовала исключения в операциях с плавающей точкой. Но в последние годы современные операционные системы, такие как Windows, macOS и Linux, и их официальные средства разработки, перестали использовать модель "floating-point exception" ("FP Exception"). То, что API-интерфейсы ОС предполагают отсутствие исключений, а Delphi RTL их использует, может привести к крашу приложения. Для решения этой проблемы разработчики Delphi ранее уже отключили исключения в операциях с плавающей точкой на платформах отличных от Windows и, чтобы избежать проблем при рендеринге изображений, в FMX под Windows. В Delphi 12 это сделали для всех платформ (Windows, macOS, iOS, Android и Linux).
В Delphi 12 и C++ Builder 12 исключения в операциях с плавающей точкой по умолчанию будут подавляться как для основных арифметических действий (сложение, вычитание, умножение и деление), так и для математических, тригонометрических (sin, cos, tan) и трансцендентных (ln, exp) функций. Для этого изменили значения по умолчанию параметров Default8087CW, DefaultMXCSR, DefaultFPSCR и DefaultFPSCR. Если ваше приложение использует исключения в операциях с плавающей точкой, то вы можете:
Таблица №2. Предыдущая конфигурация и изменения различных операций с плавающей точкой для каждой из платформ (элементы красного цвета изменены по сравнению с поведением в предыдущих версиях):
Примечания к таблице:
В Delphi 12 и C++ Builder 12 исключения в операциях с плавающей точкой по умолчанию будут подавляться как для основных арифметических действий (сложение, вычитание, умножение и деление), так и для математических, тригонометрических (sin, cos, tan) и трансцендентных (ln, exp) функций. Для этого изменили значения по умолчанию параметров Default8087CW, DefaultMXCSR, DefaultFPSCR и DefaultFPSCR. Если ваше приложение использует исключения в операциях с плавающей точкой, то вы можете:
- Восстановить старое поведение RTL вызвав из модуля System.Math глобальную функцию SetExceptionMask с параметром типа TArithmeticExceptionMask. Вызов этой функции добавляется в файл проекта (.DPR):
uses System.Math, Unit2 in 'Unit2.pas' {Form2}; {$R *.res} begin System.math.SetExceptionMask([exPrecision, exUnderflow, exDenormalized]); Application.Initialize; ...
Учитывайте то, что такие действия не являются потокобезопасными. - Обновить свой код, чтобы не использовать исключения (рекомендуемый вариант).
Платформа | Имя переменной в System | С 11.3 | С 12 |
Win/x32 Win/x64 |
Default8087CW | $1332 | $033F |
DefaultMXCSR | $1900 | $1F80 | |
macOS/x64 | DefaultFPEnv | $0032 | $003F |
macOS/Arm64 iOS/Arm64 iOS-Sim/Arm64 |
DefaultFPSCR | $0000_0700 | $0000_0000 |
Платформа и тип программы |
Старое поведение (до 11.x) | Новое поведение (с 12.0) | ||
1/0 | Sqrt (-1) | 1/0 | Sqrt (-1) | |
Win32 Win64 Default/Console/VCL |
EZeroDivide exception (*1) Result is undefined |
EInvalidOp exception (*1) Result is undefined |
No exception Result is Inf |
No exception Result is NAN |
Win32 Win64 FMX |
No exception (*2) Result is Inf |
No exception (*2) Result is NAN |
No exception Result is Inf |
No exception Result is NAN |
macOS Intel 64 FMX/Console |
No exception Result is Inf |
EInvalidOp exception Result is undefined. |
No exception Result is Inf |
No exception Result is NAN |
macOS Arm64 FMX/Console |
No exception Result is Inf |
No exception (*3) Result is NAN |
No exception Result is Inf |
No exception Result is NAN |
iOS/Arm64 FMX |
No exception Result is Inf |
EInvalidOp exception Result is undefined |
No exception Result is Inf |
No exception Result is NAN |
iOS-Sim/Arm64 FMX |
No exception Result is Inf |
EInvalidOp exception Result is undefined |
No exception Result is Inf |
No exception Result is NAN |
Android/Arm32 FMX |
No exception Result is Inf |
EInvalidOp exception Result is undefined |
No exception Result is Inf |
No exception Result is NAN |
Android/Arm64 FMX |
No exception Result is Inf |
EInvalidOp exception Result is undefined |
No exception Result is Inf |
No exception Result is NAN |
Linux/x64 Console/FMX |
No exception Result is Inf |
EInvalidOp exception Result is undefined |
No exception Result is Inf |
No exception Result is NAN |
- Зависит от используемых юнит/компонентов. Например, если приложение использует OpenGL, то оно маскирует все исключения.
- Все исключения уже отключены. System.Win.InternetExplorer маскирует все исключения. Это активируется в модуле FMX.Platform.Win.
- Этот результат был неправильным! macOS Intel 64 и Arm64 должны иметь одинаковое поведение по дизайну.
Комментариев нет:
Отправить комментарий