Compilermeldungen
Sehen wir uns nun zunächst einmal die Compilermeldungen genauer an. Diese gibt es in verschieden Gewichtungen: Hinweis, Warnung, Fehler und Fataler Fehler.
Hinweis
Hinweise sind keine eigentlichen Fehler, sondern lediglich eine Art „Erinnerung“ an den Programmierer „irgendwie scheint da etwas merkwürdig zu sein. Guck mal nach“. Beispielsweise entfernt der Compiler automatisch private Methoden, die niemals ausgeführt werden, und teilt das dem Programmierer als Hinweis mit.
Warnung
Warnungen sind Hinweise auf Fehler, die zu Exceptions oder undefiniertem Verhalten führen könnten, das erfolgreiche Kompilieren aber noch nicht beeinträchtigen. Warnungen sollte man immer kritisch betrachten, denn meist zeigen sie gravierende Programmierfehler an, die dringend behoben werden sollten. Beispiel: Wurde für eine Funktion kein Rückgabewert definiert, zeigt der Compiler eine Warnmeldung an.
Fehler
Fehler sind meist syntaktische Fehler. Diese machen ein Kompilieren unmöglich.
Fataler Fehler
Ein fataler Fehler taucht immer dann auf, wenn ein Fehler in einer Unit aufgetreten ist, die fürs Kompilieren unbedingt nötig ist. Und wenn schon eine benötigte Unit nicht kompiliert werden kann, dann kann das komplette Programm erst Recht nicht kompiliert werden.
Einige Beispiele für Hinweise
Hier reicht eigentlich schon das Lesen der Meldung um zu verstehen, was sie soll. Wird einer Variablen ein Wert zugewiesen und dieser bis zum Ende ihres Gültigkeitsbereiches nicht wieder ausgelesen, ist die Variable reichlich sinnlos. Und das merkt Delphi und benachrichtigt den, der so einem Blödsinn fabriziert hat…
Ähnlich ist es mit
Auch hier ist nicht viel zu sagen. Einfach lesen und verstehen.
Und noch ein Beispiel:
Hier ist es nur eben ein privates Feld und keine lokale Variable. Ansonsten ist das genau dasselbe.
Warnungen – Langsam wirds wichtig
Lokale Variablen werden in Delphi im Allgemeinen (Strings z.B. bilden hier eine Ausnahme) nicht vorinitialisiert, d.h. bevor man ihnen einen Wert zuweist, ist ihr Inhalt undefiniert. Wird nun eine solche Variable ausgelesen bzw. verwendet, kann dies zu unerwünschtem Verhalten führen. Das ‚möglicherweise‘ deutet darauf hin, dass in manchen Fällen der Wert undefiniert sein kann. Beispiel:
1 2 3 4 5 6 7 8 9 10 11 | begin if Anzahl < Min then begin Wert := Min; end else if Anzahl > Max then begin Wert := Max; end; ShowMessage(IntToStr(Wert)); end; |
Ist Anzahl weder kleiner als Min, noch größer als Max ist, so ist Wert undefiniert. Und weil das mit Sicherheit nicht im Sinne des Erfinders ist, meldet sich Delphi mit einer Warnmeldung.
Ganz ähnlich ist es mit
Hier ist es eben der Rückgabewert der Funktion, also die Variable Result, die möglicherweise undefiniert ist.
Erwähnenswert ist vielleicht noch folgendes:
Diese Meldung ist historisch bedingt. Der Hintergrund ist folgender: Mit Delphi6 und Kylix führte Borland die CLX(Component Library for Cross(X)-Platform Development) ein. Damit sollte es möglich sein mit demselben Code Programme für Windows und Linux zu kompilieren. Units, die jedoch plattformgebunden waren bzw. sind, d.h. die z.B. nur in einer Windows-Umgebung Sinn machen, enthalten die Direktive platform, die diese Warnmeldung erzeugt. Da die CLX und Kylix nicht mehr weiterentwickelt werden, hat diese Warnmeldung meist keine Bedeutung mehr (nur noch für die, die Kylix einsetzen) und kann deshalb ignoriert werden.
Fehler – Jetzt ist Schicht im Schacht
Der wohl beliebteste Fehler:
Delphi möchte hier zum Ausdruck bringen, dass es irgendetwas nicht kennt. Meistens ist das auf einen Tippfehler zurückzuführen. Häufig ist aber auch einfach eine benötigte Unit nicht eingebunden oder eine Variable nicht deklariert.
Der Anfängerfehler schlechthin:
Zwei Möglichkeiten: a) in der Zeile davor fehlt ein Semikolon oder b) in der Fehlerzeile fehlt ein Operator(also ein + oder sowas).
Heißt etwas umformuliert: „Eigentlich sollte hier Typ1 stehen, aber Typ2 steht da“. Beispiel:
1 | ShowMessage(3); |
ShowMessage erwartet einen String. 3 Ist aber ein Integer. Hm… was kann man da machen? Konvertieren:
1 | ShowMessage(IntToStr(3)); |
Sehr beliebt ist in diesem Zusammenhang auch das Verwechseln von String und TStrings. Dabei ist String eine einzelne Zeichenkette und TStrings eine (abstrakte) Klasse, die mehrere Strings, ähnlich wie in einem Array, zusammenfasst. Memo.Lines ist ein Beispiel dafür. So führt z.B. folgender Code zu einem Fehler:
1 | ShowMessage(Memo1.Lines); |
richtig wäre:
1 | ShowMessage(Memo1.Lines.Text); |
Was man mit Parametern noch alles falsch machen kann:
und
Die Erklärung erübrigt sich eigentlich. Delphi will nur sagen, dass man sich die Funktion nochmal gaaanz genau angucken solltest, weil man scheinbar Probleme mit dem Zählen hat…
Zum Schluss noch den Universal-Syntaxfehler schlechthin:
Meistens bedeutet das, dass man in der vorherigen Zeile ‚x‘ vergessen hat. Manchmal ist das aber auch Ausdruck eines tiefer gehenden Syntaxfehlers. ==> einfach mal in der vorherigen Zeile nachgucken, was nicht stimmt.
Alles in Allem sind Compilerfehler nichts Schlimmes. Eigentlich muss man sie nur lesen, sie verstehen und dann korrigieren. ==> kein großes Kunststück. Anfangs, wenn man Delphi noch nicht so gewohnt ist, tauchen sie andauernd auf, aber mit der Zeit lernt man immer mehr und macht immer weniger Fehler. Sowas wie „undefinierter Bezeichner“ wird mit ziemlicher Sicherheit auch später noch vorkommen, aber gerade die berühmt berüchtigten Semikolons vergisst man schon bald nicht mehr…