2009-04-05 5 views
1

Ich wunderte mich über kleine Unterschiede zwischen der Deklaration von Funktionsprototypen in Kopfzeilen und in .c-Dateien. Ich habe einen Header mit einigen Prototyp-Funktionen und einigen C-Dateien mit echter Implementierung dieser Funktionen. Ich habe einige Änderungen in der Kopfzeile vorgenommen, nur hinzugefügt "__restrict" Qualifier (von gcc erkannt). Meine Frage ist, muss ich das "__restrict" Qualifikationsmerkmal in .c-Dateien zu setzen (zur Zeit der Code kompilieren, so denke ich, die Antwort ist nein, aber eine gewisse Präzision würde geschätzt werden).C: Unterschiede zwischen Prototyp-Deklaration in der Kopf- und Funktionsdeklaration für die Implementierung?

Funktioniert dies für jeden C-Qualifier? Kann ich etwas "const" oder "volatile" im Header hinzufügen, ohne das Gleiche in .c-Dateien zu tun?

derzeit in Header:

int myfunc_gettype (const mytype *__restrict, int *__restrict); 

und in Implementierungsdatei:

int myfunc_gettype(const mytype *attr, int *type) 

Antwort

5

Sie Muss. Das Mismatch ruft undefiniertes Verhalten auf. Gibt es einen Grund, warum Sie separate Deklarationen in der Kopfzeile und bei der Definition haben möchten?

Beachten Sie, dass das Schlüsselwort restrict im Gegensatz zu __restrict ist, die eine Erweiterung des Herstellers ist (Hinweis: Blick auf die _ ist vor dem Keyword-Namen). Sie sollten die Standardversion für die Portabilität beibehalten.

+0

in der Tat das beschränken Schlüsselwort C99 ist und das __restrict ist nur durch gcc fangen mit i das gleiche Ergebnis zu erraten. – claf

+0

Ich bin mir nicht sicher zu verstehen, wenn ich das restrict Qualifier in der Kopfzeile und nicht in der Implementierung habe, wird der Zeiger sowieso "beschränken" oder nicht? – claf

+0

Sie rufen UB auf. Es kann tatsächlich dazu führen, dass der Zeiger eingeschränkt eingeschränkt wird. Das Standard-C++ - Schlüsselwort ist 'restricte', warum verwenden Sie __restrict? – dirkgently

-2

HINWEIS: Sie haben das Qualifikationsmerkmal "restrict" nicht hinzugefügt. Sie haben nur verschiedene (optionale) Variablennamen im Prototyp.

In Bezug auf Ihre Frage werden die meisten guten C-Compiler diesen Fehler abfangen und eine Warnung/einen Fehler ausgeben, wenn der nicht übereinstimmende Prototyp mit der Implementierung enthalten ist. Wenn Sie nicht übereinstimmende Prototypen haben, können Probleme vom subtilen bis zum sofortigen Absturz auftreten.

+0

Sie meinen __restrict ist ein optionaler Variablenname in der Prototyp? Ich bin mir ziemlich sicher, dass du mit gcc falsch liegst. – claf

+0

Tatsächlich hatte ich recht: "Das Schlüsselwort restrict ist ein Typqualifikator für Zeiger und ist ein formeller Teil des C99-Standards. In Code, der nicht mit C99 kompiliert werden kann, verwenden Sie entweder __restrict oder __restrict__, um das Schlüsselwort als GCC-Erweiterung zu aktivieren . " – claf

+0

Da es kompiliert wird, muss es nur ein Qualifier sein; Sie können nicht zwei Argumente mit demselben Namen haben. Ich habe mich zuerst gefragt, aber ich denke, dieses Argument ist entscheidend - vorausgesetzt, der Code kompiliert wie behauptet. –

-1

mit gcc 4.0.1, es hängt davon ab, ob die const sinnlos ist:

// Who cares, compiles fine, but irks the maintenance programmer. 

// f.h 
int f(const int i); 

// f.c 
int f(int i) { return i += 42; } 


// No no no no Your Types Conflict gcc will not stand for it 

// f.h 
int f(const int *pi); 

// f.c 
int f(int *pi) { return (*pi)+= 42; } 
+0

Es ärgert sogar die SO-Community genug, um einen Downvote zu provozieren. –

+0

Die Frage war nicht "ist das legal" oder gar "ist diese akzeptable Praxis"; es war "wird es funktionieren." –