Seltene, aber nützliche GCC-Befehlszeilenoptionen – Teil 2

Der gcc-Compiler bietet eine scheinbar endlose Liste von Befehlszeilenoptionen. Natürlich verwendet kein Körper sie alle oder hat Fachwissen darüber, aber es gibt einen ausgewählten Haufen, den jeder gcc-Benutzer wissen sollte – wenn nicht gar muss – muss. Während einige von ihnen häufig verwendet werden, sind andere etwas ungewöhnlich, aber nicht weniger nützlich.

In dieser Artikelserie konzentrieren wir uns auf einige dieser ungewöhnlichen, aber nützlichen gcc-Befehlszeilenoptionen und haben bereits einige davon im Teil 1 behandelt.

Wenn Sie sich erinnern, habe ich zu Beginn des ersten Teils dieser Tutorial-Serie kurz erwähnt, dass die Option -Wall, die Entwickler im Allgemeinen zum Erzeugen von Warnungen verwenden, einige spezifische Warnungen nicht abdeckt. Wenn Sie diese Warnungen nicht kennen und keine Ahnung haben, wie Sie sie aktivieren können, machen Sie sich keine Sorgen, da wir das alles in diesem Artikel ausführlich erklären werden.

Abgesehen davon werden wir auch eine gcc-Warnoption im Zusammenhang mit Gleitkomma-Variablen behandeln, sowie die Frage, wie man die gcc-Befehlszeilenoptionen besser verwaltet, wenn die Liste größer wird.

Aber bevor wir vorankommen, denken Sie bitte daran, dass alle in diesem Tutorial genannten Beispiele, Befehle und Anweisungen auf Ubuntu 16.04 LTS getestet wurden und die von uns verwendete gcc-Version 5.4.0 ist.

 

Warnungen aktivieren, die nicht von -Wall abgedeckt werden.

Während die Option -Wall des gcc-Compilers die meisten Warnflags abdeckt, gibt es einige, die deaktiviert bleiben. Um sie zu aktivieren, verwenden Sie die Option -Wextra Option.

Werfen Sie zum Beispiel einen Blick auf den folgenden Code:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i=0;
    /* ...
       some code here 
       ...
    */

if(i);
return 1;
return 0;
}

Ich habe versehentlich ein Semikolon nach der Bedingung „if“ gesetzt. Nun, als der Code mit dem folgenden gcc-Befehl kompiliert wurde, wurde keine Warnung ausgegeben.

gcc -Wall test.c -o test

Aber wenn die Option -Wextra verwendet wurde:

gcc -Wall -Wextra test.c -o test

Es wurde eine Warnung ausgegeben:

test.c: In function ‘main’:
test.c:10:8: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
 if(i);

Wie aus der oben dargestellten Warnung ersichtlich, hat die Option -Wextra intern das Flag -Wempty-body aktiviert, das wiederum den verdächtigen Code erkannt und die Warnung ausgegeben hat. Hier ist die vollständige Liste der Warnmerker, die durch diese Option aktiviert wurden:

-Verschlossen, -Leer-Körper, -Wignifikatoren, -Feld-Initialisierer fehlen, -Parametertyp fehlt (nur C),-Gold-Style-Deklaration (nur C), -Woverride-Init, -Wsign-Compare, -Wtype-Grenzwerte, -Wuninitialized, -Wunused-Parameter (nur mit -Wunused oder -Wall) und -Wunused-but-set-Parameter (nur mit -Wunused oder -Wall).

Wenn du wissen möchtest, was die oben genannten Flaggen bewirken, gehe auf die Man Page von gcc.

Die Option -Wextra gibt in den folgenden Fällen auch Warnungen aus:

  • Ein Pointer wird mit der Ganzzahl Null mit <, <=, <=, >, > oder >= verglichen.
  • (nur C++) Ein Enumerator und ein Nicht-Enumerator erscheinen beide in einem
    bedingten Ausdruck.
  • (nur C++) Mehrdeutige virtuelle Datenbanken.
  • (nur C++) Indizierung eines Arrays, das als Register deklariert
    wurde.
  • (nur C++) Übernahme der Adresse einer Variablen, die als Register
    deklariert wurde.
  • (nur C++) Eine Basisklasse wird im
    Kopierkonstruktor einer abgeleiteten Klasse nicht initialisiert.

Warnung für Fließkommazahlen bei Aktienvergleichen aktivieren

Wie Sie vielleicht schon wissen, sollte man nie auf die genaue Gleichheit von Gleitkommawerten testen (das wusste ich nicht – lesen Sie die FAQ zum Gleitkomma-Vergleich hier). Aber selbst wenn du dies versehentlich tust, gibt der gcc-Compiler eine Warnung oder einen Fehler aus? Lass uns mal nachsehen:

Hier ist ein Code, der Gleitkomma-Variablen mit dem ==-Operator vergleicht:

#include<stdio.h>

void compare(float x, float y)
{
if(x == y)
{
printf(„\n EQUAL \n“);
}
}

int main(void)
{
compare(1.234, 1.56789);

return 0;
}

Und hier ist der gcc-Befehl (der sowohl die Optionen -Wall als auch -Wextra enthält), mit dem dieser Code kompiliert wurde:

gcc -Wall -Wextra test.c -o test

Leider erzeugt der obige Befehl keine Warnung in Bezug auf den Gleitkomma-Vergleich. Ein kurzer Blick auf die Man Page der GCC zeigt, dass es eine spezielle Option gibt. -Wfloat-equalifiziert die in diesen Szenarien verwendet werden sollen.

Hier ist der Befehl, der diese Option enthält:

gcc -Wall -Wextra -Wfloat-equal test.c -o test

Und nachfolgend ist der Output, den sie produziert hat:

test.c: In function ‘compare’:
test.c:5:10: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
 if(x == y)

Wie Sie also in der obigen Ausgabe sehen können, hat die Option -Wfloat-equal gcc gezwungen, eine Warnung in Bezug auf den Gleitkomma-Vergleich zu erzeugen.

Hier ist, was die gcc-Manualseite über diese Option sagt:

The idea behind this is that sometimes it is convenient (for the programmer) to consider floating-point values as approximations to infinitely precise real numbers. If you are doing this, then you
need to compute (by analyzing the code, or in some other way) the maximum or likely maximum error that the computation introduces, and allow for it when performing comparisons (and when producing
output, but that's a different problem). In particular, instead of testing for equality, you shouldcheck to see whether the two values have ranges that overlap; and this is done with the relational operators, so equality comparisons are probably mistaken.

Wie man gcc Kommandozeilenoptionen besser verwaltet

Wenn die Liste der Befehlszeilenoptionen, die Sie in Ihrem gcc-Befehl verwenden, größer und schwieriger zu verwalten wird, können Sie sie in eine Textdatei einfügen und den Namen dieser Datei als Argument an den gcc-Befehl übergeben. Dazu müssen Sie die Option @file Kommandozeilenoption.

Zum Beispiel, wenn folgendes dein gcc-Befehl ist:

gcc -Wall -Wextra -Wfloat-equal test.c -o test

Dann können Sie die drei warnenbezogenen Optionen in eine Datei namens’gcc-options‘ einfügen:

$ cat gcc-options 
-Wall -Wextra -Wfloat-equal

Und Ihr gcc-Befehl wird weniger überladen und einfach zu verwalten:

gcc @gcc-options test.c -o test

Hier ist, was die gcc-Manualseite über @file sagt:

Read command-line options from file. The options read are inserted in place of the original @file option. If file does not exist, or cannot be read, then the option will be treated literally, and not removed.

Options in file are separated by whitespace. A whitespace character may be included in an option by surrounding the entire option in either single or double quotes. Any character (including a backslash) may be included by prefixing the character to be included with a backslash. The file may itself contain additional @file options; any such options will be processed recursively.

Fazit

So haben wir in dieser Tutorial-Serie insgesamt 5 ungewöhnliche, aber nützliche gcc-Befehlszeilenoptionen behandelt: -save-temps, -g, -Wextra, -Wfloat-equal und @file. Verbringe Zeit damit, jeden von ihnen zu üben und vergiss nicht, alle Details durchzugehen, die die gcc-Manualseite über sie bietet.

Kennst du andere so nützliche gcc-Befehlszeilenoptionen und möchtest sie mit der Welt teilen? Hinterlasse alle Details in den Kommentaren unten.

Das könnte dich auch interessieren …