2015-09-24 3 views
0

Недавно я обновил свое приложение с Delphi 2007 до Delphi XE8. В нескольких формах линия Form.showmodel генерирует исключение «с плавающей запятой на ноль». На этих формах нет никаких арифметических операций вообще.Деление с плавающей точкой на ноль на showmodal Delphi XE8

Я попытался выполнить следующий код перед showmodal, который разрешил проблему.

var 
    CW, SW: word; 

    function GetX87CW: word; 
    ASM 
    FStCW [Result] 
    End; 

    Function GetX87SW: word; // Assembler; 
    ASM 
    FStSW [Result] 
    End; 

    CW := GetX87CW; SW := GetX87SW; 

    ShowMessage(Format('CW = $%4x, SW = $%4x',[CW,SW])); 

Я не сохранил этот код и не прокомментировал весь код и снова перекомпилировал приложение, которое также разрешило проблему.

Теперь я закрыл Delphi и перезапустил XE8 IDE. Я открыл проект, и этот вопрос снова появился, но на этот раз, хотя я написал вышеприведенный код, он все еще бросает исключение.

Есть ли кто-нибудь, кто видел такую ​​проблему, и кто-то может рассказать о возможной причине такой проблемы?

+0

Вы не поставили достаточно информации. Что вы делаете? Такая проблема никогда не появится с простым приложением Delphi. –

+0

Ничто в этой форме не является стандартным или COM или даже Windows API. Он имеет пару Tlistview и TADODataset для доступа к базе данных. Очень странная часть - это работа на Delphi 2007, но не на Delphi XE8. – DivX

+0

без вопросов здесь без [mcve] –

ответ

0

Вы используете COM-объекты, например. вызова .Net-сборок? Или OpenGL? Или некоторые поставщики OleDB/ADO? Любая другая внешняя .dll? Полагаю, что так.

Звучит как this issue. Вы должны попытаться сделать внешний вызов не Delphi безопасным, сохраняя и восстанавливая флаги исключений FPU для каждого вызова.

Как Кен писал:

var 
    Saved8087CW: Word; 
begin 
    Saved8087CW := Default8087CW; 
    // If you want, disable all fpu exceptions 
    // with the next line. 
    Set8087CW($133F); 
    DoYourComOperationHere; 
    Set8087CW(Saved8087CW); 
end; 
+0

Хотя будьте осторожны, что Set8087CW не является потокобезопасным, и поэтому этот подход нельзя использовать, если более одного потока вызывает Set8087CW. –

+0

Спасибо за информацию Дэвид. – DivX

+0

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