LCLint – lint für die, die es wirklich besser machen wollen

Nachdem sich Lint schon früh zu einem Standard zur Qualitätsuntersuchung von C-Quellcode entwickelt hat, stiegen die Ansprüche an ein solches Werkzeug. Es gibt eine Reihe von Fehlerkategorien, die man in seinem C-Programm erzeugen kann, die Lint jedoch nicht findet.

Daher wurde das bessere Lint, LCLint, geboren, welches heute im NASA Langley Research Center weiter entwickelt wird. Dem Programmierer steht das Kommando lclint zur Verfügung, welches nicht nur eine ganze Reihe der traditionellen Lint-Überprüfungen wie Typüberprüfung, Benutzung undefinierter Variablen, ignorierte Funktionsergebnisse oder unbenutzte Deklarationen zur Verfügung stellt, sondern dem Profi Funktionalitäten für Macros, Aliasing, Namenskonventionen, Speicher-Sharing etc. bietet.

Um sich mit LCLint vertraut zu machen, versucht man am besten die gleiche Taktik wie mit Lint: Man probiert es aus. Der erste Versuch bringt bereits eine ganze Reihe von Information:

> lclint sample.c

Für den Anfänger ist es aber einfacher, LCLint mit der Option -weak (für schwache Überprüfung) aufzurufen, denn die meisten C-Programme produzieren derart viele Meldungen, dass man vor lauter Text zurückschreckt. Das hat LCLint aber nicht verdient und soll daher zuerst mit der Beginner-Option betrachtet werden:

>lclint -weak sample.c

Was dabei herauskommt, ist schon weitaus überschaubarer und erinnert nicht von ungefähr an die Ausgabe des Klassikers Lint:

sample.c: (in function main)
sample.c:27,3: Assignment of long int to short int: kurz = lang
To ignore type qualifiers in type comparisons use +ignorequals.
sample.c:20,7: Variable unbenutzt declared but not used
A variable is declared but never used. Use /*@unused@*/ in front of
declaration to suppress message. (-varuse will suppress message)

Erster Bonus zu Lint: LCLint gibt die Spalte aus, in der es etwas gefunden hat. Hier bemerkt LCLint in der Zeile 27 ab der Spalte 3 die Zuweisung der vier Byte langen long-Variablen auf die ein Byte lange short-Variable. Mit der Option -weak wird zusätzlich erkannt, dass es eine Variable gibt, die zwar deklariert wurde aber nicht benutzt wird.

Optionen

Was uns dieses erste kleine Beispiel lehrt, ist, wie man beim Aufruf von LCLint Optionen setzen oder deaktivieren kann. Sollen Fehlermeldungen zum Typkonflikt nicht mehr ausgegeben werden, so geht das einfach – wie schon der Fehlertext beschreibt – mit:

> lclint -weak +ignorequals sample.c

Hier sehen wir eine etwas Unix-untypische Vorgehensweise beim Setzen der Optionen: Während mit einem Pluszeichen eine Option gesetzt wird, deaktiviert ein Minus sie wieder. Die Plus/Minus-Optionen sollen Klarheit verschaffen, können aber aufgrund ihrer vom Unix-Standard abweichenden Form Verwirrung stiften. Daher ist es sehr angenehm, dass Fehlermeldungen sagen, wie eine Option zu setzen ist (im obigen Beispiel mit -varuse will suppress message).

Es ist noch zu bemerken, dass LCLint über 300 Optionen kennt, die man nicht alle eintippen möchte, wenn man LCLint aufruft. Daher können die Standardoptionen in der Datei .lclintrc im aktuellen Verzeichnis dauerhaft gesichert werden. Die hier gesetzten Optionen überschreiben die allgemeinen Einstellungen in der Datei ~/.lclintrc im Home-Verzeichnis des Anwenders. Letztendlich ist die Angabe einer Option beim Aufruf natürlich maßgeblich und überschreibt die vorbestimmten Einstellung der Datei .lclintrc.

In Listing 2 (using.c) sieht man die Möglichkeit, stilisierte Kommentare (engl. stylized comments) zu benutzen. Sie sind einer der ganz großen Vorteile von LCLint gegenüber dem klassischen lint-Befehl, da sie es ermöglichen, LCLint-Anweisungen und Zusatzinformationen in den Quelltext einzubauen.

Listing 2

using.c

1 int main()
2 {
3  int ungebraucht;
4  /*@unused@*/
5  int braucheIchNoch;
6
7   return 0;
8 }

Auf dieses Listing reagiert LCLint mit der folgenden Ausgabe:

using.c: (in function main)
using.c:3,7: Variable ungebraucht declared but not used
  A variable is declared but never used. Use /*@unused@*/ in front of
  declaration to suppress message. (-varuse will suppress message)

Der Nichtgebrauch der Variablen braucheIchNoch wurde LCLint durch die Kommentierung mit /*@unused@*/ als gültig gemeldet. Es erfolgt keine Fehlermeldung. Gleichzeitig ist die Variable ungebraucht nicht entsprechend markiert; demzufolge wird sie von LCLint angemeckert.

Doch nun zum besseren Lint. Dazu lassen wir einfach die Option -weak einmal weg und sehen uns an, was LCLint standardmäßig ausgibt, wenn wir es auf unser Listing 1 losjagen (Kasten "Ausgabe von lclint sample.c").

Ausgabe von

lclint sample.c
sample.c: (in function main)
sample.c:27,3: Assignment of long int to short int: kurz = lang
  To ignore type qualifiers in type comparisons use +ignorequals.
sample.c:28,8: Variable undefiniert used before definition
  An rvalue is used that may not be initialized to a value on some execution
  path. (-usedef will suppress message)
sample.c:30,3: Statement has no effect: lang == effektlos
  Statement has no visible effect — no values are modified. (-noeffect will
  suppress message)
sample.c:35,21: Return value (type int) ignored: g()
  Result returned by function call is not used. If this is intended, can cast
  result to (void) to eliminate message. (-retvalint will suppress message)
sample.c:37,3: Return value (type int) ignored: rueckgabe()
sample.c:38,2: Path with no return in function declared to return int
  There is a path through a function declared to return a value on which there
  is no return statement. This means the execution may fall through without
  returning a meaningful result to the caller. (-noret will suppress message)
sample.c:20,7: Variable unbenutzt declared but not used
  A variable is declared but never used. Use /*@unused@*/ in front of
  declaration to suppress message. (-varuse will suppress message)
  • Die erste und die letzte Meldung kennen wir bereits aus dem Beispiel mit der Option -weak; auf diese brauchen hier nicht nochmals eingehen.
  • Die zweite Meldung erklärt, dass die Variable undefiniert uninitialisiert zugewiesen wird (das hat der Lint schon herausbekommen).
  • Die dritte Meldung ist neu, denn hier erkennt LCLint, dass das Ergebnis der Zeile 30 keinen Effekt hat. Da hier mit dem doppelten Gleichheitszeichen gearbeitet wird, ist das Resultat dieses Vergleichs der Wert false, denn lang hat den Wert 3 und effektlos den Wert 1, womit aus dem Vergleich 1==3 das Ergebnis false berechnet wird. Dieses wird jedoch nicht weiter gebraucht oder zugewiesen, also hat LCLint schon ganz recht, wenn er diese Zeile als effektlos erkennt.
  • Die vierte Meldung ist ebenfalls neu; sie wurde vom Lint nicht ausgegeben. LCLint bemerkt, dass die Funktion g() einen Wert vom Typ int zurückgibt, dieser jedoch nicht weiter verwendet wird. Der häufigste Fehler dieser Art wird bei der C-Programmierung beim Öffnen einer Datei mit der Systemfunktion fopen() gemacht. Diese gibt nämlich einen Returncode zurück, welcher dokumentiert, ob das Öffnen der Datei überhaupt geklappt hat. Oft wird dieser Returncode gar nicht erst überprüft, sondern einfach nur die Funktion alleine aufgerufen, so wie in unserem Beispiel sample.c die Funktion g() aufgerufen wird.
  • Die fünfte Meldung ist gleichbedeutend mit der vierten; das Beispiel soll nur noch einmal verdeutlichen, dass der Fehler nicht etwa an der While-Schleife liegt.
  • Die sechste Fehlermeldung ist aus der Betrachtung von Lint bekannt. Die Funktion main() gibt keinen Wert zurück, obwohl sie es nach ihrer Deklaration machen sollte.

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

  • Splint und Co: Tools zur statischen Code-Analyse
    Zwar finden Compiler Syntaxfehler in Programmen, aber auch syntaktisch korrekter Code kann Ungenauigkeiten, logische Fehler oder veraltete Funktionen beinhalten. Solche Probleme spüren Sie mit Quellcode-Analyzern auf.
  • Im Innern der Muschel
    Mit der Version 4 erhält die Bourne Again Shell (Bash) neue Funktionen, die sie einmal mehr als leistungsfähige Programmierschnittstelle zum System und zu Applikationen qualifiziert.
  • Entwicklungshelfer
    Nachdem in den ersten Teilen der Python-Einführung die Sprache beschrieben wurde, geht es im letzten Teil um nützliche Hilfen rund um Python.
  • Erste Schritte mit Bash-Skripten
    Das Programmieren von Shell-Skripten ist keine Hexerei. Schon mit wenigen Grundkenntnissen sparen Sie durch das Automatisieren alltäglicher Aufgaben viel Zeit.
Kommentare

Infos zur Publikation

LU 11/2014: VIDEOS BEARBEITEN

Digitale Ausgabe: Preis € 4,95
(inkl. 19% MwSt.)

Mit der Zeitschrift LinuxUser sind Sie als Power-User, Shell-Guru oder Administrator im kleinen Unternehmen monatlich auf dem aktuelle Stand in Sachen Linux und Open Source.

Sie sind sich nicht sicher, ob die Themen Ihnen liegen? Im Probeabo erhalten Sie drei Ausgaben zum reduzierten Preis. Einzelhefte, Abonnements sowie digitale Ausgaben erwerben Sie ganz einfach in unserem Online-Shop.

NEU: DIGITALE AUSGABEN FÜR TABLET & SMARTPHONE

HINWEIS ZU PAYPAL: Die Zahlung ist auch ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!       

Tipp der Woche

Schnell Multi-Boot-Medien mit MultiCD erstellen
Schnell Multi-Boot-Medien mit MultiCD erstellen
Tim Schürmann, 24.06.2014 12:40, 0 Kommentare

Wer mehrere nützliche Live-Systeme auf eine DVD brennen möchte, kommt mit den Startmedienerstellern der Distributionen nicht besonders weit: Diese ...

Aktuelle Fragen

WLAN-Signalqualität vom Treiber abhängig
GoaSkin , 29.10.2014 14:16, 0 Antworten
Hallo, für einen WLAN-Stick mit Ralink 2870 Chipsatz gibt es einen Treiber von Ralink sowie (m...
Artikelsuche
Erwin Ruitenberg, 09.10.2014 07:51, 1 Antworten
Ich habe seit einige Jahre ein Dugisub LinuxUser. Dann weiß ich das irgendwann ein bestimmtes Art...
Windows 8 startet nur mit externer Festplatte
Anne La, 10.09.2014 17:25, 6 Antworten
Hallo Leute, also, ich bin auf folgendes Problem gestoßen: Ich habe Ubuntu 14.04 auf meiner...
Videoüberwachung mit Zoneminder
Heinz Becker, 10.08.2014 17:57, 0 Antworten
Hallo, ich habe den ZONEMINDER erfolgreich installiert. Das Bild erscheint jedoch nicht,...
internes Wlan und USB-Wlan-Srick
Gerhard Blobner, 04.08.2014 15:20, 2 Antworten
Hallo Linux-Forum: ich bin ein neuer Linux-User (ca. 25 Jahre Windows) und bin von WIN 8 auf Mint...