AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Floating Point Exception oder Access Violation, je nach Schreibweise

Floating Point Exception oder Access Violation, je nach Schreibweise

Ein Thema von Der schöne Günther · begonnen am 12. Dez 2017 · letzter Beitrag vom 15. Dez 2017
Antwort Antwort
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.108 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 12. Dez 2017, 18:04
Delphi-Version: 10 Seattle
Kann mir jemand folgendes Verhalten erklären?

uses System.Generics.Collections; Prozedur p1 wirft eine Access Violation, p2 hingegen eine Floating point invalid operation. Warum? Da ist doch kein Unterschied!

Delphi-Quellcode:
procedure p1();
type
   TFloat = type Single;
var
   values:   TArray<TFloat>;
begin
   values := [1.0, Single.Nan, 2.0];
   TArray.Sort<TFloat>(values);
end;

procedure p2();
type
   TFloat = Single;
var
   values:   TArray<TFloat>;
begin
   values := [1.0, Single.Nan, 2.0];
   TArray.Sort<TFloat>(values);
end;

Geändert von Der schöne Günther (12. Dez 2017 um 18:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 12. Dez 2017, 18:15
Doch schon. Mit X = type Y deklarierst du ja einen neuen Strong-Type und nicht nur einen Alias. Vergleiche über TypInfo, RTTI, oder eben die Intrinsics im Zusammenhang mit der generischen TArra<T>.Sort Methode werden hierbei dann keine Gleichheit mehr ergeben.

Edit:
Die generischen Container haben in Delphi für die meisten Standard-Typen spezifische Behandlungsroutinen. Dadurch, dass der RTL TFloat bzw. type Single unbekannt ist, wird hier dann vermutlich auf eine Fallbackroutine zurückgegriffen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (12. Dez 2017 um 20:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#3

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 13. Dez 2017, 02:13
Aber "Zugriffsverletzung" kommt mir dennoch etwas komisch vor.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#4

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 13. Dez 2017, 03:00
Ratet mal, wofür es den Debugger gibt.

Wie Zacherl bereits erwähnte, gehört dein neuer Typ nicht zu den bekannten "Default"-Typen, für Welche in Delphi passende Comparer existieren,
also wird hier ganz einfach nur auf Type-Size gegangen und der Inhalt "Binär" verglichen.

Delphi-Quellcode:
class procedure TArray.Sort<T>(var Values: array of T);
begin
  QuickSort<T>(Values, TComparer<T>.Default, Low(Values), High(Values));
end;

class function TComparer<T>.Default: IComparer<T>;
begin
  Result := IComparer<T>(_LookupVtableInfo(giComparer, TypeInfo(T), SizeOf(T)));
end;

class procedure TArray.QuickSort<T>(var Values: array of T; const Comparer: IComparer<T>; L, R: Integer);
begin
  ...
      while Comparer.Compare(Values[I], pivot) < 0 do


// Single
function Compare_R4(Inst: Pointer; const Left, Right: Single): Integer;
begin
  if Left < Right then

// type Single
function Compare_U4(Inst: Pointer; const Left, Right: Cardinal): Integer;
begin
  if Left < Right then
Du mußt dir also selber einen Comparer erstellen, für solche Typen.
TArray.Sort<TFloat>(Values, Comparer);

Die Zugriffsverletzung ist aber ein schwerwiegender Bug im QuickSort.
Ich bin echt erstaunt, daß es nicht öfters knallt.

Mit Single knallt es schon im Compare, wegen des NAN und weil die FPU so eingestellt ist.
> Delphi-Referenz durchsuchenSet8087CW Delphi-Referenz durchsuchenSetExceptionMask

Bei type Single funktioniert der Vergleich, da "NAN" dort nicht behandelt wird, und es knallt im QuickSort.
Das erste while Comparer.Compare(Values[I], pivot) < 0 do Inc(I); findet kein Ende und trifft hier "zufällig" irgendwann auf nicht zugewiesenen Speicher.
Das Selbe wird man auch bei anderen Typen hinbekommen. Der BufferOverflow wird zum Glück abgefangen, da die Array-Grenzen im Anschluss geprüft werden und somit keine Schreibzugriffe außerhalb des Arrays auftreten.
Es knallt also immer wenn im Array und davor oder dahinter auch kein fremder reservierter Speicher mit einem passenden Wert gefunden wird.

Delphi-Quellcode:
class procedure TArray.QuickSort<T>(var Values: array of T; const Comparer: IComparer<T>; L, R: Integer);
var
  I, J: Integer;
  pivot, temp: T;
begin
  if (Length(Values) = 0) or ((R - L) <= 0) then
    Exit;
  repeat
    I := L;
    J := R;
    pivot := Values[L + (R - L) shr 1];
    repeat
      while Comparer.Compare(Values[I], pivot) < 0 do
        Inc(I);
      while Comparer.Compare(Values[J], pivot) > 0 do
        Dec(J);

Sehr eigenartig ist auch, dass in diesem Generic die Bereichsprüfung nicht funktioniert.
> {$RANGECHECKS ON} bzw. in den Projektoptionen aktiviert
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#5

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 13. Dez 2017, 03:19
https://quality.embarcadero.com/brow...22quicksort%22
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#6

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 14. Dez 2017, 21:36
LOL, grade gefunden.
http://www.delphipraxis.net/182907-d...-overflow.html

Der Witz dabei ist, das du hier schon mit dem Bugfix arbeitest. (neuer Code, der ebenfalls nicht funktioniert)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.008 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 15. Dez 2017, 09:41
Sehr eigenartig ist auch, dass in diesem Generic die Bereichsprüfung nicht funktioniert.
> {$RANGECHECKS ON} bzw. in den Projektoptionen aktiviert
Guck mal ganz oben in System.Generics.Collections ...
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.108 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 15. Dez 2017, 09:52
Danke für die Erklärung, jetzt verstehe ich es zumindest.

Und ja, ein Floating Point-Error wäre mir auf jeden Fall lieber als eine AV.

PS: Dein Kommentar in
https://quality.embarcadero.com/browse/RSP-19091
ist wohl nochmal einen neuen Eintrag wert, die haben das Ticket danach einfach zu gemacht
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#9

AW: Floating Point Exception oder Access Violation, je nach Schreibweise

  Alt 15. Dez 2017, 10:18
PS: Dein Kommentar in
https://quality.embarcadero.com/browse/RSP-19091
ist wohl nochmal einen neuen Eintrag wert, die haben das Ticket danach einfach zu gemacht
Sorry, hatte nur in 'er 10.2 Release 1 geguckt , aber JIRA is och nich dat Schnellste.
Es gibt 'nen Bugfix ... du mußt ihn dir nur kaufen.

Muß nur nochmal wer Testen, ob's wirklich geht.
Zitat:
List of new features and customer reported issues fixed in RAD Studio 10.2 Tokyo Release 2

RSP-19091
Stackoverflow error in TArray.QuickSort and System.Classes.QuickSort
RTL, RTL\Delphi
http://edn.embarcadero.com/article/44770
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (15. Dez 2017 um 10:20 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz