![]() |
Re: Handling von Fehlern, Warnungen und Hints
*schnipps* *meld*
Ah... Wieso nicht einfach bei Hack-Units die Warnungen ausschalten? Solche Units basieren eh auf dem Compiler und sind weder Plattform- noch Compilerunabhängig, weil auf bestimmte Registerkonventionen, Stackaufbau usw. gebaut wird. Man umgeht in so einem Hack sowieso (aus Performancegründen oder weil es anders einfach nicht geht) das Bestreben einer modernen Programmiersprache, schwere Fehler zu vermeiden und setzt sich bewusst der Gefahr aus, das System zu zerballern. |
Re: Handling von Fehlern, Warnungen und Hints
Zitat:
|
Re: Handling von Fehlern, Warnungen und Hints
Naja, es gibt einfach Situationen in denen man mit nem "dreckigen Hack" mehrere Stunden umständliche Programmierung sparen kann.
Man muss nur wirklich wissen, was man tut und sollte sich auf keinen Fall auf fremde Hacks verlassen (wenn man sie nicht versteht). |
Re: Handling von Fehlern, Warnungen und Hints
Zitat:
|
Re: Handling von Fehlern, Warnungen und Hints
Wenn ich da an
![]() |
Re: Handling von Fehlern, Warnungen und Hints
Zitat:
Bei Hack-Units, die von privaten Projekten entwickelt und gepflegt werden, würde ich so eine Aussage jedoch nicht sofort und ohne weiteres Unterschreiben. |
Re: Handling von Fehlern, Warnungen und Hints
Es geht ja garnicht darum, dass du fremde Units verwendest, sondern ggf. auch darum, dass du evtl selbst solche Hacks verwendest.
|
Re: Handling von Fehlern, Warnungen und Hints
Hallo ich habe mal den Sachverhalt von Dezipaitor in einem kompilierbaren Beispiel verdeutlicht.
Vorgehensweise zum selbst Testen:
Dei Kommentare im Code sollten alles erklären. mfg MaBuSE
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; // Hier werden die kompletten Funktionen definiert // Im implementation Teil darf dann die Definition etwas abgekürzt werden // (Z.B. darf der Rückgabetyp weggelassen werden.) function TestIt1: Pointer; function TestIt2: Pointer; function TestIt3: Pointer; function TestIt4: Pointer; implementation {$R *.dfm} var _TestIt1: Pointer; _TestIt2: Pointer; function TestIt1; begin // Der Variable _TestIt1 wird das Ergebnis zugewiesen, das hat nix mit Result // zu tun -> Result ist undefiniert und war bei meinen Tests nicht immer nil! _TestIt1 := @Form1; end; function TestIt2; begin // Der Variable _TestIt2 wird die Adresse der Funktion TestIt3 zugewiesen, // das hat nix mit Result zu tun -> Result ist noch undefiniert. _TestIt2 := @TestIt4; // Hier wird direkt in die TestIt4 Funktion gesprungen // -> also zu dem Result := @Form1 , danach wird nur ein RET duchgeführt. // Damit ist in dem EAX-Register zur Rückgabe der Wert @Form1 enthalten // und das Result wurde damit implizit gesetzt. asm JMP _TestIt2 end; end; // Hier funktioniert es nicht, da der Compiler erkennt, das TestIt4 das // EAX-Register verändert. Deshalb baut er beim Begin ein Push EBX ein // Das Result würde nun in EBX gespeichert und beim end; wieder in EAX // kopiert und der ursprüngliche EBX Wert wieder hergestellt (pop ebx). // Damit ist das Result wieder undefiniert ;-) function TestIt3; begin // ASM: 53 - push ebx TestIt4; // ASM: E806000000 - call TestIt4 end; // ASM: 8BC3 - mov eax,ebx // ASM: 5B - pop ebx // ASM: C3 -ret function TestIt4; begin Result := @Form1; // ASM: B8C80C4600 - mov eax, @Form1 end; // ASM: C3 - ret procedure TForm1.Button1Click(Sender: TObject); var p: Pointer; begin // Anmerkung die p := nil; Zeilen werden vom Compiler alle wegoptimiert. // Sie dienen nur der Übersichtlichkeit ;-) p := nil; p := TestIt1; // p ist undefiniert (kann, muß aber nicht nil sein) Memo1.Lines.Add('p = $'+ IntToHex(Integer(p),8)); Memo1.Lines.Add('_TestIt1 = $'+ IntToHex(Integer(_TestIt1),8)); p := nil; p := TestIt2; // in p steht das richtige Ergebnis Memo1.Lines.Add('p = $'+ IntToHex(Integer(p),8)); Memo1.Lines.Add('_TestIt2 = $'+ IntToHex(Integer(_TestIt2),8)); p := nil; p := TestIt3; // p ist undefiniert (kann, muß aber nicht nil sein) Memo1.Lines.Add('p = $'+ IntToHex(Integer(p),8)); p := nil; p := TestIt4; // in p steht das richtige Ergebnis Memo1.Lines.Add('p = $'+ IntToHex(Integer(p),8)); end; end. |
Re: Handling von Fehlern, Warnungen und Hints
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Handling von Fehlern, Warnungen und Hints
Zitat:
Delphi-Quellcode:
{$WARN W1035 OFF} // Warnung "W1035 Rückgabewert der Funktion <name> könnte undefiniert sein" unterdrücken.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz