Delphi-PRAXiS
Seite 6 von 9   « Erste     456 78     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Handling von Fehlern, Warnungen und Hints (https://www.delphipraxis.net/120816-handling-von-fehlern-warnungen-und-hints.html)

alzaimar 18. Sep 2008 09:33

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.

HeikoAdams 18. Sep 2008 10:08

Re: Handling von Fehlern, Warnungen und Hints
 
Zitat:

Zitat von alzaimar
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.

Das wäre für mich eher ein Grund, solche Units soweit möglich zu meiden. Auch wenn man für Software, die das System zerballert, nicht haftbar gemacht werden kann, der Ruf ist dann schnell ruiniert.

SubData 18. Sep 2008 10:11

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).

alzaimar 18. Sep 2008 10:15

Re: Handling von Fehlern, Warnungen und Hints
 
Zitat:

Zitat von HeikoAdams
Das wäre für mich eher ein Grund, solche Units soweit möglich zu meiden. Auch wenn man für Software, die das System zerballert, nicht haftbar gemacht werden kann, der Ruf ist dann schnell ruiniert.

Die System.pas müsstest Du dann meiden ;-) ebenso wie diverse low-level und performanceoptimierte Routinen. Was meinst du, wie es hinter den Kulissen von dot.Net aussieht?

SubData 18. Sep 2008 10:20

Re: Handling von Fehlern, Warnungen und Hints
 
Wenn ich da an FastCode denke... Holla ;-)

HeikoAdams 18. Sep 2008 10:25

Re: Handling von Fehlern, Warnungen und Hints
 
Zitat:

Zitat von alzaimar
Die System.pas müsstest Du dann meiden ;-) ebenso wie diverse low-level und performanceoptimierte Routinen. Was meinst du, wie es hinter den Kulissen von dot.Net aussieht?

Ich denke mal, das man Hack-Units, die von CodeGear ausgeliefert werden zumindest soweit getestet sind, das sie keine größeren Schäden anrichten.

Bei Hack-Units, die von privaten Projekten entwickelt und gepflegt werden, würde ich so eine Aussage jedoch nicht sofort und ohne weiteres Unterschreiben.

SubData 18. Sep 2008 10:26

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.

MaBuSE 18. Sep 2008 10:34

Re: Handling von Fehlern, Warnungen und Hints
 
Hallo ich habe mal den Sachverhalt von Dezipaitor in einem kompilierbaren Beispiel verdeutlicht.

Vorgehensweise zum selbst Testen:
  • Quelltext der Unit komplett markieren und kopieren (Strg+C)
  • Neue Anwendung erstellen einen TButton drauf, ein TMemo drauf.
  • Den Button doppelklicken -> Quelltextfenster mit Methoden erscheint.
  • Kompletten Quelltext mit Strg+A markieren und durch Strg+V mit dem aus der Zwischenablage ersetzen.
  • Kopileren und debuggen.

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.

Dezipaitor 18. Sep 2008 10:35

Re: Handling von Fehlern, Warnungen und Hints
 
Zitat:

Zitat von HeikoAdams
Zitat:

Zitat von Dezipaitor
"Rückgabewert der Funktion AddSecurityPackageW könnte undefiniert sein" - Das ist hier falsch.
Hier ein "result := " einzufügen wäre wahnsinnig, da man ein paar tausend Funktionen anpassen müsste.

Das bedeutet im Umkehrschluss, das Du vom Compiler erwartest, das er bei Funktionen nicht nur nach "Result :=" oder "Funktionsname :=" suchen soll, sondern auch noch eventuell vorhandenen ASM-Code parsen soll, ob eventuell dort das entsprechende Register bestückt wird?

Nein, natürlich nicht. Aber wenn es sowas wie {$WARN UNDEFINED_RESULT OFF} und {$WARN UNDEFINED_RESULT DEFAULT} gegeben hätte, dann wären nun über 3000 Funktionen, die semantisch korrekt einen Rückgabewert liefern, ohne diese Warnungen. Dadurch würden Warnungen aufgedeckt, die auch stimmen.

Zitat:

Sorry, aber wer zu faul ist, "Result :=" oder "Funktionsname :=" in seine Funktion zu schreiben, der hat nichts anderes als die entsprechende Warnung verdient. :evil:
Ich glaube, du wärst auch zu faul, dies in über 3000 Funktionen einzubauen. Zudem wäre das ein beträchtlicher Anstieg von Code in der Binärdatei. Außerdem ist jeder Aufruf mit Zeitverlust verbunden, da, wenn von Delphi nicht herausgerechnet, ja auch Code ausgeführt wird. Und bei einer Library weiß man nie wie oft die Funktionen aufgerufen werden. Würde ich nur wegen den Warnungen überall, ein Result einfügen, dann würde ich sicherlich eine Menge Mails deshalb bekomme, warum der Code so groß geworden ist (bei vielen Funktionsaufrufen).

Zitat:

Ebenso gefährlich finde ich, das es überhaupt die Möglichkeit gibt, Warnungen für ein gesamtes Projekt zu deaktivieren. Nur weil die Warnungen im Moment unbegründet sind, darf man als verantwortungsvoller Entwickler nicht davon ausgehen, dass das auch zukünftig der Fall ist!
Es ist viel gefährlicher, wenn man von ungültigen Warnungen bomadiert wird und bei einer riesigen Liste die echten Warnungen nicht mehr sieht. Zudem dauert die Erstellung von Projekten mit vielen Warnungen sehr lange. Es mag für den Anwendungsentwickler nicht von belang sein, aber für große Projekte und Libs ist das nicht förderlich.

Zitat:

Zitat:

Zitat von Dezipaitor
Globale Variablen werden schon immer mit 0 initialisiert.
Das ist ein dokumentiertes Verhalten und wird sicher nicht in Zukunft geändert.

Dazu sage ich nur: Verlass Dich auf andere und Du bist verlassen.
Wer sagt Dir, das es nicht zukünftig einen (ge)wichtigen Grund für CodeGear gibt, das beschriebene Verhalten doch zu verändern?
Garantie wird es keine geben. Da es jedoch dokumentiert ist, kann man sich darauf verlassen, dass die Kompatibilität beibehalten und bei einer Änderung frühzeitig bescheid gegeben wird. Wäre das nicht so, würden eine Menge Delphianwendungen von heute auf morgen nicht mehr funktionieren. Das kann ich garantieren. Schließlich wird auch nicht plötzlich die Prozedur Inc geändert, so dass sie dekrementiert.

Zitat:

Mein Informatik-Lehrer hat uns förmlich eingeprügelt, anstellen von
Delphi-Quellcode:
if a <= b then
nur
Delphi-Quellcode:
if (a <= b) then
zu schreiben, da man nie sicher sein kann, das sich das Verhalten des Compilers in diesem Punkt nicht doch irgendwann ändert.
Sein Credo war damals: Im Leben ist nur eins sicher: Man stirb früher oder später.
Klammern zu schreiben ist ja ok. Besonders wenn es größere Bedinungen gibt, ist das ein muss. Aber es ist normal, dass man in der Lehre etwas härter darauf trainiert wird, niemandem und nichts zu vertrauen. Aber wenn man das auf die Wirtschaft übertragen würde, würde es wohl einen Stillstand geben.


Zitat:

Zitat von alzaimar
*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.

Man kann es nicht für diese Units allein ausschalten, da WARNINGS OFF global, also für alle Units gilt. Wenn der compiler einmal an diese Direktive angekommen ist, dann gibt es danach für eigene Units keine Warnungen mehr.

MaBuSE 18. Sep 2008 10:43

Re: Handling von Fehlern, Warnungen und Hints
 
Zitat:

Zitat von Dezipaitor
Nein, natürlich nicht. Aber wenn es sowas wie {$WARN UNDEFINED_RESULT OFF} und {$WARN UNDEFINED_RESULT DEFAULT} gegeben hätte, dann wären nun über 3000 Funktionen, die semantisch korrekt einen Rückgabewert liefern, ohne diese Warnungen. Dadurch würden Warnungen aufgedeckt, die auch stimmen.
...
Zitat:

Zitat von alzaimar
... Wieso nicht einfach bei Hack-Units die Warnungen ausschalten? ...

Man kann es nicht für diese Units allein ausschalten, da WARNINGS OFF global, also für alle Units gilt. Wenn der compiler einmal an diese Direktive angekommen ist, dann gibt es danach für eigene Units keine Warnungen mehr.

Das ist auch der Grund warum ich mir in Fragen an CodeGearThread gewünscht habe, dass man einzelne Warnungen über die Nummer und nicht nur über die Gruppe ausschalten kann.
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.
Seite 6 von 9   « Erste     456 78     Letzte »    

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