2016-09-05 6 views
3

Ich habe auf ein Stück Code arbeiten, die ein übersehen derp in sich hatte:Wie undefinierte Präprozessor-Makro mit gcc zu fangen?

#include<stdio.h> 
#include<stdlib.h> 
#include<limits.h> 

#define MAX_N_LENGTH 

/*function prototypes*/ 

int main(){ 
... 
} 

Es sollte mit dem Kontext zu erkennen, entfernt werden einfach: #define MAX_N_LENGTH#define MAX_N_LENGTH 9 gelesen haben sollte. Ich habe keine Ahnung, wohin diese nachlaufende Konstante gegangen ist.

Da dieses Makro nur an einer Stelle in Form von char buf[ MAX_N_LENGTH + 1] verwendet wurde, war es extrem schwierig, das Programm aufzuspüren und zu debuggen.

Gibt es eine Möglichkeit, Fehler wie diese mit dem GCC-Compiler zu fangen?

+1

* Bitte vermeiden Sie die Beantwortung der Frage in Kommentaren. * – user1717828

+0

'char buf [MAX_N_LENGTH + 1]' wird als 'char buf [+1]' erweitert, das ist gültig und 'gcc' Warnt nicht vor gültigem Code. –

Antwort

1

Es ist nicht möglich, diesen Fehler im allgemeinen Sinne zu finden, weil es kein Fehler ist. Es gibt viele Fälle, in denen diese Art von Verhalten erwünscht ist, so dass der Compiler sie nicht als Fehler oder Warnung behandeln kann.

Wenn Sie den Fehler bis zu einer Zeile verfolgen können, verursacht die Verwendung des Befehlszeilenarguments -E von gcc die Ausgabe des Ergebnisses des Präprozessors. In diesem Fall wäre Ihre Char-Zeile zu char buf[+1] geworden, was legaler C-Code ist, aber möglicherweise Ihre Aufmerksamkeit erregt, weil Sie erwartet haben, dass es char buf[9+1] ist. -E bewirkt, dass gcc diese Ergebnisse druckt, sodass Sie in der Ausgabe von gcc tatsächlich char buf[+1] sehen würden.

Fragen wie diese sind, warum C++ Verwendung von Makros definieren auf diese Weise schreckt (C++, hat natürlich mehr Alternativen als C, die es leichter zu entmutigen sie macht)

+0

Zukünftige Googler: siehe auch [PSkociks Antwort hier] (https://stackoverflow.com/a/39335483/1717828); Ich könnte nur eins akzeptieren, aber sie sind beide ausgezeichnet. – user1717828

1

Was haben Sie da nicht ein undefinierter Makro. Es ist ein leeres Makro. Und definierte leere Makros sind absolut legitim, weil man auf ihre Definiertheit testen kann.

Sie werden in den Implementierungsheaderdateien ziemlich häufig verwendet, obwohl sich all diese leeren Makros im Implementierungsnamensbereich befinden, was bedeutet, dass sie entweder zwei Unterstriche oder einen Unterstrich gefolgt von einem Großbuchstaben enthalten.

Was könnten Sie tun, ist testen, ob Sie ein leeres Makro haben, die nicht in der Umsetzung Namespace ist, und Sie können das tun, mit:

cpp -dM YOUR_FILE.c | 
    cut -d\ -f2- | grep '^[a-zA-Z0-9_]* $' |grep -v -e __ -e ^_[A-Z] 

Für Ihr Beispiel, es ausgeben sollte nur MAX_N_LENGTH.

3

Sie können char buf[1 + MAX_N_LENGTH] verwenden, da char buf[1 +] sollte nicht mit der Fehlermeldung kompilieren error: expected expression before ']' token:

http://ideone.com/5m2LYw

+0

Sie meinen 'char buf [MAX_N_LENGTH + 1]' –

+1

@AlterMann nein, 'char buf [+1]' kompiliert, während 'char buf [1+]' kompiliert nicht. – mch

+0

Oh Entschuldigung, du hast Recht !! (Kurzschluss) –

1

Sie den Präprozessor verwenden können, zu fangen, wenn ein Makro entweder 0 oder ohne Wert definiert:

#define VAR 

#if VAR+0 == 0 
#error "VAR is either 0 or defined without a value." 
#endif 
Verwandte Themen