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
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ä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 02/2016: Alt-PCs flott machen

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!       

Der Tipp der Woche

Schon gewußt?

14.11.2015

Auch unter Ubuntu 15.10 kann man wieder mit dem Startmedienersteller (alias Startup Disk Creator) ein Live-System auf einem USB-Stick einrichten. ...

Fehler des Startmedienerstellers von Ubuntu 15.10 umgehen

Aktuelle Fragen

Tails Update
Val Lerie, 11.01.2016 10:51, 0 Antworten
Hallo zusammen, updaten > update Speichern unter > Persistent nicht möglich, mit der Meldung;...
Recoll
Jürgen Heck, 20.12.2015 18:13, 4 Antworten
Wie kann man mit Recoll nach bestimmten Zeichen/Satzzeichen bzw. Zeichenkombinationen suchen, z....
Wings Platinum 4 auf Linux?
Bodo Steguweit, 18.12.2015 11:37, 4 Antworten
Hallo in die Runde ich nutze für meine Diashows Wings Platinum 4 als Diareferent. Arbeite jetzt...
Bandbreite regulieren
Georg Armani, 25.11.2015 16:50, 1 Antworten
Hallo, ich bin ein Neuling in Sachen Linux und hoffe auf Hilfe. Ich habe zwei Windows Rechner...
Windows 10 verhindert LINUX
Hans Wendel, 17.11.2015 17:47, 8 Antworten
Hallo alle, mit einem W10-Laptop (vorher war Win7) wollte ich LINUX ausprobieren. Alles, was ni...