Schleifen --> verwirrt

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.

Re: Schleifen --> verwirrt

Beitragvon Socke » 10. Apr 2018, 11:24 Re: Schleifen --> verwirrt

m.fuchs hat geschrieben:Was ich eher schmerzlich vermisse ist die Möglichkeit bei einem dynamischen Array den Startindex zu setzen.

Ich vermisse das nicht. Der Startindex ist immer der niedrigste Ordinalwert des Index-Datentyps. In VBA hatte mich der Code eines Kollegen einmal so verwirrt, dass bis heute das erste Element des Arrays einfach nicht ausgegeben wird :oops: Wobei man in Pascal mit Low() und High() auch das recht elegant und fehlerunanfällig verwenden könnte.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2498
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon Warf » 10. Apr 2018, 16:44 Re: Schleifen --> verwirrt

mischi hat geschrieben:
Warf hat geschrieben:Über ranges kann man nunmal auch statische arrays definieren, daher hast du ein 26*26 Felder 2D array. Ein wenig verwirrend, vor allem da ich kein fan der range array definierung bin. Ich finde das C system mit nur anzahl an elementen dafür immer 0 basiert deutlich besser

Es hindert dich doch nichts daran, deine Arrays mit 0 .. n-1 zu deklarieren. Das ist doch nur etwas mehr Schreibarbeit bei der Deklaration. Die Flexibilität von Pascal Arrays hat einige Vorteile. In Fortran beginnen alle Arrays mit dem Index 1 und das ist in einigen Fällen praktischer. Durch seine Flexibilität kann ich also in Pascal Code aus C UND Fortran direkt übernehmen, ohne dass ich etwas mit den Laufvariablen und Grenzen machen muss. Manchmal kommen einem auch Real-World Probleme auf den Tisch, bei denen weder bei 0 noch bei 1 angefangen wird zu zählen, sondern bei irgendeiner anderen Zahl. Ich habe immer wieder die Erfahrung gemacht, dass es überraschend häufig zu Fehlern kommt, wenn man das umsetzen muss, obwohl man denkt, dass es doch nicht so schwierig sein kann, eine Eins oder einen anderen Wert abzuziehen.


Kann aber auch zu vielen Missverständnissen führen. Einfaches Beispiel. Mehrere Leute arbeiten an einem Pascal Projekt. Frisch von der Uni hat Alice noch nie vorher Pascal verwendet und ist nur etwas bewandert in Java, Bob hingegen ist ein alt eingefuchster Pascal Profi.
Das Projekt selbst ist ein etwas länger bestehendes größeres program an dem neben Alice und Bob mehrere Entwickler dran sitzen, sagen wir einfach mal 5000 Lines of Code welches und einige statische Arrays drin hat. Alice, wie es die meisten Anfänger die von Java kommen so machen, iteriert über statische wie dynamische Arrays mit for i:=0 to Length(array)-1 (da iht schlicht weg die Übung mit Low und High fehlt).
Jetzt ändert Bob irgendwo das untere limit eines statischen Arrays auf 1, da die neue Datenstruktur die ID's mit 1 beginnt und damit der Array Index der ObjektID gleich sein soll (was ja grundsätzlich eine ausgezeichnete Idee ist).

Bob commited diese Änderung ins git, merged den spaß dann mit der Arbeit der letzten zwei Wochen und plötzlich funktioniert gar nichts mehr wie erwartet. Jetzt heißt es 2 Wochen an code changes von verschiedenen Entwicklern durchgehen um zu finden wo dieser Fehler aufgetreten ist. Also mit mindestens 5 stunden Arbeitszeit sollte man dafür schon rechnen.

So ähnlich ist es mir mal passiert, 1,5 Tage sind mir damals flöten gegangen nur um den Fehler zu finden. Man bekommt ja auch keine Fehlermeldung wenn man mal eben neben ein statisches array schreibt (Und range Checks musste ich deaktivieren da mir die dauernd false positives geworfen haben).
Daher fange ich bei statischen array ausnahmslos immer mit 0 an, denn selbst erfahrenen Pascal Programmierern passiert es auch mal das man for i:=0 to length()-1 statt high und Low macht

PS: Fortran ist außerdem eine komplette nieschensprache, die kaum noch wer außerhalb von Physiklaboratorien verwendet. Also so irrelevant das jemand der heute programmieren lernt wahrscheinlich nie eine Zeile Fortran sehen wird (außer er ist Physik student), und das eine mal das das in der Lebzeit eines Programmierers mal passiert kann man auch ein -1 hinschreiben
Zuletzt geändert von Warf am 10. Apr 2018, 17:38, insgesamt 1-mal geändert.
Warf
 
Beiträge: 830
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon Mathias » 10. Apr 2018, 17:09 Re: Schleifen --> verwirrt

Daher fange ich bei statischen array ausnahmslos immer mit 0 an, denn selbst erfahrenen Pascal Programmierern passiert es auch mal das man for i:=0 to length()-1 statt high und Low macht
Wen es irgendwie geht, fange ich auch immer bei '0' an. high und low verwende ich nie.
Da bekommt man sonst lustige Sachen, wie das Beispiel:
Code: Alles auswählen
var
  sa: array[10..20] of byte;
 
procedure Ausgabe(a: array of byte);
var
  i: integer;
begin
  for i := 0 to Length(a) - 1 do begin
    WriteLn(a[i]);
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i := 10 to 20 do begin
    sa[i] := i;
  end;
  Ausgabe(sa);
end;


Da hat C++ ausnahmsweise einen Vorteil, da kann man die Array in etwa so deklarieren:
Code: Alles auswählen
var
  sa: array[10] of byte;

Da muss man nicht immer 0.. schreiben.

Eine besondere Array gibt es in Pascal, den String.
Der fängt bei 1 an. Aber dies wird eine Altlast von Turbo-Pascal sein, bei dem das 0. Zeichen die Länge angibt. Oder den heutigen FPC ShortString.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3977
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Warf » 10. Apr 2018, 17:32 Re: Schleifen --> verwirrt

Mathias hat geschrieben:
Daher fange ich bei statischen array ausnahmslos immer mit 0 an, denn selbst erfahrenen Pascal Programmierern passiert es auch mal das man for i:=0 to length()-1 statt high und Low macht
Wen es irgendwie geht, fange ich auch immer bei '0' an. high und low verwende ich nie.
Da bekommt man sonst lustige Sachen, wie das Beispiel:
Code: Alles auswählen
var
  sa: array[10..20] of byte;
 
procedure Ausgabe(a: array of byte);
var
  i: integer;
begin
  for i := 0 to Length(a) - 1 do begin
    WriteLn(a[i]);
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i := 10 to 20 do begin
    sa[i] := i;
  end;
  Ausgabe(sa);
end;


Da hat C++ ausnahmsweise einen Vorteil, da kann man die Array in etwa so deklarieren:
Code: Alles auswählen
var
  sa: array[10] of byte;

Da muss man nicht immer 0.. schreiben.

Eine besondere Array gibt es in Pascal, den String.
Der fängt bei 1 an. Aber dies wird eine Altlast von Turbo-Pascal sein, bei dem das 0. Zeichen die Länge angibt. Oder den heutigen FPC ShortString.


Lustig wird's erst wenn du auf den array out of Bounds schreibst. Wenn dein array eine globale Variable ist und im data teil liegt, kann es gerne passieren das du andere globale variablen überschreibst. Wenn du dann plötzlich den Pointer zu einer deiner Forms überschrieben hast wird es richtig lustig, wenn dir Form1.ShowModal() aus einer komplett anderen unit plötzlich eine SegFault wirft und du keine Ahnung hast woher das kommt :twisted: .

Und das mit den Strings wird aktuell zum glück über die Typhelper geändert. Wenn man statt Str[Index] Str.Chars[Index] verwendet ist es null basiert (sowie alle type helper Funktionen von string). Lustig dabei wird es aber wenn man Str.Substring (0 basiert) und Pos (1 basiert) o.ä. verknüpft. Daher verwende ich aktuell auch fast ausschließlich die Typhelper, da die 0 basiert sind und ich da nicht extra drüber nachdenken muss
Warf
 
Beiträge: 830
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon m.fuchs » 10. Apr 2018, 18:32 Re: Schleifen --> verwirrt

Warf hat geschrieben:Einfaches Beispiel. Mehrere Leute arbeiten an einem Pascal Projekt.
[...]
Jetzt ändert Bob irgendwo das untere limit eines statischen Arrays auf 1, da die neue Datenstruktur die ID's mit 1 beginnt und damit der Array Index der ObjektID gleich sein soll (was ja grundsätzlich eine ausgezeichnete Idee ist).

Bob commited diese Änderung ins git, merged den spaß dann mit der Arbeit der letzten zwei Wochen und plötzlich funktioniert gar nichts mehr wie erwartet. Jetzt heißt es 2 Wochen an code changes von verschiedenen Entwicklern durchgehen um zu finden wo dieser Fehler aufgetreten ist. Also mit mindestens 5 stunden Arbeitszeit sollte man dafür schon rechnen.

Klingt nach schlechter Architektur, fehlender Kapselung und ungenügenden Unittests.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1946
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon Warf » 10. Apr 2018, 19:23 Re: Schleifen --> verwirrt

m.fuchs hat geschrieben:Klingt nach schlechter Architektur, fehlender Kapselung und ungenügenden Unittests.


Ich hatte mich damals um das design der Datenstruktur sowie das laden und speichern zu kümmern. Der Pascal Anfänger war dann mit den Auswertungsalgorithmen für diese Datenstruktur zu tun. Wir hatten also eine strikte kapselung zwischen IO und Verarbeitung, sowie uns an alle OOP Standards gehalten. Um genau zu sein hat diese kapselung zwischen IO und Verarbeitung dafür gesorgt das ich den Bug zunächst im IO code gesucht hab, wodurch es sogar länger gedauert hat.

Und zu Unittests, was denkst du wie wir den Bug überhaupt gefunden haben? Ohne gute test Suites hat man praktisch keine Chance so einen Fehler überhaupt zu entdecken. (Denn Arr[0] schluckt der Computer einfach selbst wenn der Array erst bei 1 anfängt).

Um dir mal zu zeigen wie einfach es ist einen Fehler zu machen:
Sagen wir wir haben eine Unit SomeTestUnit mit einer Globalen Variable SomeVal:
Code: Alles auswählen
Unit SomeTestUnit;
 
interface
 
var SomeVal: Integer;
 
implementation
 
end.


Dann gibt dieser Code auf meinem Mac (fpc 3.0.4, OSX 10.13.1 High Sierra) -1 zurück:
Code: Alles auswählen
program test;
 
uses
  SomeTestUnit;
 
var
  arr: array[20..50] of Integer;
  i: Integer;
begin
  for i:=0 to Length(arr)-1 do arr[i] := -1;
  WriteLn(SomeVal);
end.


Da nützt kapselung, Gute Architektur und Unit test gar nix, denn ich habe grade eine Globale Variable einen Wert zugewiesen in dem Programm ohne einen einen expliziten Schreibzugriff auf SomeVal. Und das komplett ohne Fehlermeldung o.ä. Für mich als user sieht es so aus als wäre das program ohne Fehler durchgelaufen.

Um das ganze mal auf die Spitze zu treiben, sagen wir mal du hast eine Globale variable einen Zeiger auf einem Config record, der alle Einstellungen wie Formgröße, Position, etc von deinem Programm speichert.

Jetzt hast du bei der Programmnutzung irgendwo eine stelle die genau den Fehler macht den ich oben gepostet habe, welcher den Pointer auf die Config überschreibt. Beim versuch die Config zu schreiben versucht das Programm dann den neuen ungültigen Pointer zu dereferenzieren, und sagen wir mal wir sind im Worst case, und keine SegFault fliegt dir um die Ohren. Stattdessen wird nur Müll gelesen und in die Config geschrieben. Beim nächsten lesen der config ist plötzlich alles falsch. Dein Fenster ist nicht mehr sichtbar, und beim Debuggen findest du heraus das einfach die Left und Top Koordinaten außerhalb des Bildschirms liegen.

Wo suchst du den Fehler? Im Config Load? im Config Write? in einer von hunderten For schleifen irgendwo zwischen 5000 Zeilen code, welche zufällig durch die Test suite nicht abgedeckt wurde, denn niemand glaubt man könnte eine simple füll mit Wert schleife über einem array verkacken (und test Suites sind nie allumfangend und testen oftmals solche Kleinigkeiten nicht)?

Das ist eine ganz gefährliche Fehlerquelle, die eigentlich bereits schon vom Sprachdesign selbst ausgeschlossen werden könnte. mMn. Ist das von der Fehleranfälligkeit auf dem selben Niveau wie C string Arithmetik
Zuletzt geändert von Warf am 10. Apr 2018, 19:31, insgesamt 1-mal geändert.
Warf
 
Beiträge: 830
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon Mathias » 10. Apr 2018, 19:31 Re: Schleifen --> verwirrt

So ähnlich ist es mir mal passiert, 1,5 Tage sind mir damals flöten gegangen nur um den Fehler zu finden. Man bekommt ja auch keine Fehlermeldung wenn man mal eben neben ein statisches array schreibt (Und range Checks musste ich deaktivieren da mir die dauernd false positives geworfen haben).

Wieso hast du nicht an der Stelle mit dem "false" ein {$R-} gesetzt und nacher wieder ein {$R+} ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3977
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Warf » 10. Apr 2018, 19:38 Re: Schleifen --> verwirrt

Mathias hat geschrieben:
So ähnlich ist es mir mal passiert, 1,5 Tage sind mir damals flöten gegangen nur um den Fehler zu finden. Man bekommt ja auch keine Fehlermeldung wenn man mal eben neben ein statisches array schreibt (Und range Checks musste ich deaktivieren da mir die dauernd false positives geworfen haben).

Wieso hast du nicht an der Stelle mit dem "false" ein {$R-} gesetzt und nacher wieder ein {$R+} ?


Weil mir range Checks an so vielen stellen um die Ohren fliegen das ich sie immer global aus habe. Früher habe ich z.B. sehr oft solche Konstrukte gehabt:
Code: Alles auswählen
Move(Arr1[0], Arr2[0], Len);

Wo mir der Rangeindicator immer um die Ohren geflogen ist (leerer array). Und da mein Programm einen string parser enthielt, kamen solche Konstrukte so oft vor, das ich range Checks einfach global ausgeschaltet habe.

Mittlerweile habe ich solche Konstrukte deutlich seltener, da ich für Strangs einfach .substring vom Typhelper verwenden kann, früher kam diese Zeile aber in den meisten meiner Programme mindestens einmal vor
Warf
 
Beiträge: 830
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon mischi » 10. Apr 2018, 19:44 Re: Schleifen --> verwirrt

Warf hat geschrieben:PS: Fortran ist außerdem eine komplette nieschensprache, die kaum noch wer außerhalb von Physiklaboratorien verwendet. Also so irrelevant das jemand der heute programmieren lernt wahrscheinlich nie eine Zeile Fortran sehen wird (außer er ist Physik student), und das eine mal das das in der Lebzeit eines Programmierers mal passiert kann man auch ein -1 hinschreiben

Des einen Nische, des anderen täglich (Physik-)Brot und genau deshalb ist mir die Flexibilität wichtig. Probleme mit false positives bei range checks hatte ich noch nie. Das habe ich bei Testläufen immer an und mach das nur bei zeitaufwendigen Produktionsläufen aus. Das mit der -1 für den Index hört sich einfach an, aber bei komplexeren Algorithmen kann das schnell unübersichtlich werden. Meistens ist die Verführung, den Ausdruck zu reduzieren, zu groß und bei einem von 20 Fällen wird ein Vorzeichen verschlampt.
MiSchi macht die fink-Pakete
mischi
 
Beiträge: 196
Registriert: 10. Nov 2009, 18:49
OS, Lazarus, FPC: macOS, 10.13, lazarus 1.8.x, fpc 3.0.x | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon mischi » 10. Apr 2018, 19:53 Re: Schleifen --> verwirrt

Warf hat geschrieben:Weil mir range Checks an so vielen stellen um die Ohren fliegen das ich sie immer global aus habe. Früher habe ich z.B. sehr oft solche Konstrukte gehabt:
Code: Alles auswählen
Move(Arr1[0], Arr2[0], Len);

Wo mir der Rangeindicator immer um die Ohren geflogen ist (leerer array). Und da mein Programm einen string parser enthielt, kamen solche Konstrukte so oft vor, das ich range Checks einfach global ausgeschaltet habe.

Hätte man da nicht besser gleich Pointer verwendet? Ich brauch das selten, weil meine arrays normalerweise die gleiche Länge haben und man einfach Arr2 := Arr1 machen kann.
Zuletzt geändert von mischi am 10. Apr 2018, 19:55, insgesamt 1-mal geändert.
MiSchi macht die fink-Pakete
mischi
 
Beiträge: 196
Registriert: 10. Nov 2009, 18:49
OS, Lazarus, FPC: macOS, 10.13, lazarus 1.8.x, fpc 3.0.x | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon Mathias » 10. Apr 2018, 19:53 Re: Schleifen --> verwirrt

Wo mir der Rangeindicator immer um die Ohren geflogen ist (leerer array).
Mit diesem Problem bin ich auch schon konfrontiert worden. Als bei OpenGL ein Vertex-Array aus 0 Zeichen bestand.
Mit
Code: Alles auswählen
Pointer(GLfloatArray) anstelle von @GLfloatArray[0]
war ich das Problem los.
Bei Move würde ich ein if Len > 0 then einfügen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3977
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 10. Apr 2018, 19:55 Re: Schleifen --> verwirrt

Hätte man da nicht besser gleich Pointer verwendet?

Dies habe ich gerade versuch, geht aber nicht, da nicht die eigentlich Daten verschoben werden, sondern die Speicherbereiche, in dem sich Die Zeiger auf die Array befinden.
Mit einer statischen Array könnte es gehen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3977
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon mischi » 10. Apr 2018, 20:08 Re: Schleifen --> verwirrt

Warf hat geschrieben:Um dir mal zu zeigen wie einfach es ist einen Fehler zu machen:
Sagen wir wir haben eine Unit SomeTestUnit mit einer Globalen Variable SomeVal:
Code: Alles auswählen
Unit SomeTestUnit;
 
interface
 
var SomeVal: Integer;
 
implementation
 
end.


Dann gibt dieser Code auf meinem Mac (fpc 3.0.4, OSX 10.13.1 High Sierra) -1 zurück:
Code: Alles auswählen
program test;
 
uses
  SomeTestUnit;
 
var
  arr: array[20..50] of Integer;
  i: Integer;
begin
  for i:=0 to Length(arr)-1 do arr[i] := -1;
  WriteLn(SomeVal);
end.


Bei mir (fpc 3.0.4, OSX 10.13.4 High Sierra) kommt ohne range check 0 raus. Etwas besser, aber auch nicht gut. Hab vielleicht andere Voreinstellungen. Mit range check (-Cr) kommt ein run time error. In schönem Pascal code würde man aber auch einen subrange typ 20..50 deklarieren und beim array und bei i verwenden. Dann gibt es auch schon prompt einen Fehler beim Kompilieren. Zeigt das Beispiel nicht eher, dass man in Pascal auch C-ähnlich programmieren kann, sich dann aber auch mit den gleichen Problemen rumschlagen muss.
MiSchi macht die fink-Pakete
mischi
 
Beiträge: 196
Registriert: 10. Nov 2009, 18:49
OS, Lazarus, FPC: macOS, 10.13, lazarus 1.8.x, fpc 3.0.x | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon m.fuchs » 10. Apr 2018, 20:14 Re: Schleifen --> verwirrt

Warf hat geschrieben:Um das ganze mal auf die Spitze zu treiben, sagen wir mal du hast eine Globale variable einen Zeiger auf einem Config record, der alle Einstellungen wie Formgröße, Position, etc von deinem Programm speichert.

Ich denke wir können die Diskussion an dieser Stelle beenden. Also falls du meinst, dass du mit dem aufgezählten Dingen und deinem geposteten Quellcode noch von Architektur und Kapselung sprichst.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1946
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon Warf » 10. Apr 2018, 20:36 Re: Schleifen --> verwirrt

m.fuchs hat geschrieben:Ich denke wir können die Diskussion an dieser Stelle beenden. Also falls du meinst, dass du mit dem aufgezählten Dingen und deinem geposteten Quellcode noch von Architektur und Kapselung sprichst.


Oh wenn dir mein Beispiel nicht gut genug ist machen wir doch aus der globalen variable eines Record Zeigers einfach die Variable xxxForm: TxxxForm die von lazarus automatisiert erstellt wird und von der LCL benötigt wird. Und irgendwann rufst du xxxForm.ShowModal auf und es kracht. Ist im grunde das selbe Szenario mit der selben Problematik. Oder sagen wir mal du überschreibst die locale und bekommst plötzlich den Fehler: 123.456 ist kein gültiger Float wert, obwohl du extra amerikanische locale verwendest.
Oder sind dir diese szenarien auch zu abstrakt? verwendest du etwa gar keine Lazarus forms oder FoatToStr?

Wenn du noch ein einfacheres Beispiel möchtest:
Code: Alles auswählen
procedure Foo();
var
  i: Integer;
  arr: array[15..30] of Integer;
  Bar: TBar;
begin
  //Bar wird initialisiert
  // 40 Zeilen sonstiger Code
  for i:=0 to Length(arr)-1 do arr[i] := -1;
  // 40 Zeilen sonstiger code
  Bar.FooBar;
end;

Bei Bar.FooBar bekommst du eine SegFault, Irgendwo inmitten von fast 100 Zeilen Code ist diese For schleife versteckt. Ich würde schätzen mindestens 1 stunde aufwand den Fehler zu finden. Das ist eine komplette stunde in der man unproduktiv ist nur wegen einem kleinen Fehler. Obwohl der code hier sehr künstlich ist, sind diese szenarien doch alle sehr real. Jetzt stell dir vor Bar wird nicht lokal ausgeführt sondern als Parameter an die nächste Funktion gegeben, returned, oder irgendwo anders abgelegt sodass der Fehler erst wo ganz anders auftritt.

Oder was ist wenn du die rücksprungaddresse des frames der vorigen Funktion mit +=3 überschreibst und plötzlich in einer komplett anderen Funktion 3 instructions übersprungen werden? Wie du den Fehler suchst will ich sehen.

Wenn du lust hast nimm einfach mal ein kleines test Projekt, und pass Start und Endindex deines Arrays beliebig an. Du kannst beliebig viel kaputt machen. Wenn dein Array z.B. ein Feld eines Objektes ist, kannst du einfach mal andere Felder überschreiben. Wenn es eine Lokale variable ist kannst du alle lokalen variablen des aktuellen Stack frames sowie aller vorigen stack frames überschreiben, sowie die Rücksprung oder die self Adresse. Als globale Variable kannst du alle globalen Variablen überschreiben. Das Fehlerpotential ist unerschöpflich. Je nach Architektur kannst du sogar den eigenen quellcode ändern (was bei der virtuellen Harvard Architektur moderner Betriebsysteme nicht so einfach geht). Und von den möglichen Sicherheitslücken falls man das array mit userinput füllt will ich gar nicht erst anfangen

Ich kenne kein anderes Pascal Feature was so eine hohe Fehleranfälligkeit hat, die sich selbst mit C messen kann
Zuletzt geändert von Warf am 10. Apr 2018, 21:11, insgesamt 5-mal geändert.
Warf
 
Beiträge: 830
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

» Weitere Beiträge siehe nächste Seite »
VorherigeNächste

Zurück zu Sonstiges



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried