2016-12-01 6 views
1

ich vor kurzem erfahren, dass es parameter-type-lists ist, die in C leer sein:Wie findet man die Verwendung von Parameter-Typ-Listen in einer C-Code-Basis?

int print(); 

int main() { 
    print("hallo"); // << valid but highly unintuitive 
} 

int print() { 
} 

In diesem Code jemand habe nur vergessen print(void) (vielleicht einen C++ Entwickler) zu schreiben, aber jemand bietet sonst einen Parameter. Compilation zeigt keine Warnungen oder Fehler:

$ make test -Wstrict-prototypes -Wimplicit -Wimplicit-function-declaration -Wall 
cc  test.c -o test 

Ich habe keinen Compiler-Flag finden, die über leere Parameter-Typ-Listen warnen, nur implizite Funktionsdeklaration.

Gibt es etwas, was ich tun kann, das mir hilft, alle Verwendungen von Parameter-Typ-Listen in einer gegebenen Codebasis zu finden?

z.

  • letting a C++ compiler compile the C code as C++ und lösen Art Fragen (C++ erlaubt keine Argumente, wenn die Erklärung sie nicht aufführen)
  • den Compiler Liste alle Funktionsdeklarationen lassen (weiß nicht, wenn möglich) und
  • manuell für leere Klammern gesucht
  • grep ing für Parameter-Typ-Listen (zu komplex für mich :))
  • deaktivieren Parameter-Typ-Listen über Compiler-Schalter (das fand jede nicht)
+2

Sie können C-Code nicht mit einem C++ - Compiler kompilieren! C++ ist eine andere Sprache und identische Syntax impliziert keine identische Semantik. C++ ist ** nicht ** "C mit Klassen"! Und Parameter-Typ-Listen sind genau das, was Sie ** für korrekte C verwenden müssen. Alles andere ist seit 17 Jahren veraltet und veraltet. Nicht klar, was du erreichen willst. – Olaf

+0

http://Stackoverflow.com/a/861556/1668622 – frans

+0

Sie haben Recht, aber die Unterschiede zu gültigen C++ - Code sind genau das, was ich versuche zu finden - das Problem ist, ich werde viel mehr Probleme finden als beabsichtigt:) – frans

Antwort

0

Alles, was Sie brauchen zu suchen ist () (mit optionalen Leerzeichen), gefolgt von { (mit optionalen Leerzeichen, vielleicht Newline). Und Sie können es durch (void) ersetzen.

Wenn Sie eine "industrial grade" -Lösung möchten, können Sie einen Compiler verwenden, der etwas leichter zu analysieren, wie GCC-XML oder Clang.

+0

Dies wäre definitiv eine Antwort, wenn es ein Beispiel gäbe. Und es ist der zweite und dritte Ansatz, den ich in meiner Frage aufgeführt habe. Aber da es überall Leerzeichen und Zeilenumbrüche geben kann, führt das für mich zur Regex/Flucht-Hölle. – frans

2

mit gcc, mit -Wstrict-Prototypen wird erreichen, was Sie erwarten:

-Wstrict-Prototypen (C und Objective-C nur) Warnen, wenn eine Funktion deklariert oder definiert, ohne die Angabe Argumenttypen. (. Eine alte Stil Funktionsdefinition wird ohne Warnung zulässig, wenn durch eine Erklärung voraus, die Argumenttypen gibt)

Mit Ihrem Beispiel gibt es:

hallo.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes] 
int print() { 
    ^

Allerdings müssen Sie haben um sicherzustellen, dass alle nicht-strikten Funktionsdeklarationen in Ihrem vorhandenen Code richtig definiert werden; insbesondere Funktionen ohne Parameter mit (void) erklärt werden soll, wie folgt aus:

int print(void); 
+0

Das ist gut, wenn das OP GCC verwendet, aber nicht abgeschlossen. Wenn es überhaupt keine Deklaration der Funktion 'print()' gibt, dann gibt es nichts, worüber '-Wsstrikt-Prototypen' warnen könnten. –

+1

Aber ich werde über 'int print() {..}' (ohne void) gewarnt und zusammen mit '-Wimplicit-function-declaration' muss ich * einen vollständigen Prototyp bereitstellen. Wenn ich 'print (" hallo ") anrufen möchte:' – frans

1

Ihr Beispiel ist nicht gültig, weder in C noch in C++. Da Ihre print() Funktion keine Parameter akzeptiert - was von der Funktion Definition gut ist, die Sie angeben (C2011, 6.7.6.3/14) - ist es nicht konform, es mit einem Argument aufzurufen, unabhängig davon, ob a der Prototyp ist zum Zeitpunkt des Anrufs sichtbar (C2011, 6.5.2.2/6).Wenn der Aufruf in einem Bereich erscheint, in dem weder die Funktionsdefinition noch ein Prototyp sichtbar ist, kann der Compiler den Code dennoch akzeptieren, aber das macht ihn nicht gültig oder garantiert, dass er funktioniert.

Darüber hinaus scheinen Sie den falschen Begriff zu verwenden, oder möglicherweise ist Ihre Idee sehr falsch. Parameter-Typ-Listen sind die moderne Art und Weise (und die Definition) Funktionen deklarieren, einschließlich Funktionsprototypen:

int my_func(int a, char *b); 
//   ^^^^^^^^^^^^^^----- parameter-type-list 

Sie sollten nicht die loszuwerden, aber ich denke, Sie meinen, dass Sie identifizieren wollen und beheben K & R-Stil Funktionsdefinitionen und auch Funktionsdeklarationen ohne Parameter-Typ-Listen. (Die Syntax der Bedingungen für den K & R Stil sind „Bezeichner“ und, falls erforderlich, eine begleitende „Deklarationsliste“).

Wie für das Auftreten von K & R-Style Deklarationen automatisch identifiziert, das ist ein Job für einen C-Sprachen-Parser, und die gebräuchlichsten Implementierungen von diesen sind C-Compiler. Ihr Compiler hat möglicherweise eine Option für genau das, was Sie wollen. GCC zum Beispiel hat die Optionen -Wstrict-prototypes und -Wold-style-defintion, die zusammen sowohl Funktionsdeklarationen signalisieren, die keine Prototypen sind, als auch K & R-Stil-Funktionsdefinitionen. GCC hat einige andere Optionen, die Sie auch interessieren könnten, wie -Wimplicit, -Wtraditional und -Wc++-compat.

+0

Nun, deine Antwort klingt tiefgründig, vielleicht verstehe ich es nicht. Mein Problem ist, dass der Compiler ** 'void print() {..}' akzeptiert und mit Argumenten aufruft. Vielleicht ist meine Formulierung falsch .. – frans

+0

@frans, wenn Ihr Compiler den Funktionsaufruf mit einem Argument akzeptiert, obwohl die Funktionsdefinition keine Parameter angibt, dann gibt es entweder keinen Prototyp für diese Funktion im Bereich zum Zeitpunkt des Aufrufs oder der Compiler ist fehlerhaft. Wenn Sie GCC verwenden, wird es vor Aufrufen zu nicht deklarierten Funktionen warnen, wenn Sie '-Wimplicit' (oder' -Wall') verwenden. Wenn Sie in diesem Fall auch "-Wstrict-Prototypen" verwenden, kennzeichnet GCC Funktionsdeklarationen, die keine Prototypen bereitstellen. Mit dieser Kombination sollte Ihr Code nicht über GCC hinausgehen, ohne irgendeine Art von Diagnose auszulösen. –

+1

hast du das tatsächlich versucht? http://stackoverflow.com/a/13950800/1668622 schlägt vor, dass es veraltet, aber gültig ist. '-Wstrict-prototypes' findet, was ich suche, also enthält Ihre Antwort * die * Lösung, sagt aber etwas anderes .. – frans

Verwandte Themen