2016-05-25 12 views
1

Ich habe dieses Erbe MakroUngültige Speicherklasse für eine Funktion in einem Makro in GCC

#define ASYNC_FUNCTION(x)            \ 
void x(void) {               \ 
    static void internal ## x (ASYNCIOCB *);       \ 
    ASYNCIOCB *aiocb = AcquireAsyncIOCB();        \ 
    CallAsyncNativeFunction_md(aiocb, internal ## x);     \ 
}                  \ 
static void internal ## x (ASYNCIOCB *aiocb) 

gefolgt von diesem

#define ASYNC_FUNCTION_START(x) ASYNC_FUNCTION(x) { 
#define ASYNC_FUNCTION_END  ASYNC_resumeThread(); } 

Und ihre Verwendung sieht wie folgt aus:

ASYNC_FUNCTION_START(Occasional_function_name) 
{ 
    //actual stuff  
} 
ASYNC_FUNCTION_END 

Es kompiliert fein mit cl, aber gcc gibt

invalid storage class for function ‘internalOccasional_function_name’ 
    static void internal##x (ASYNCIOCB *);  
       ^

Ich habe versucht, sie alle zu erweitern, nur um zu sehen, was es wird und nichts gebrochen gefunden. Ich suchte auch für nicht geschlossene geschweiften Klammern in der Datei und fand andere Makros wie diese

#define Foo_Bar1() {            \ 
    extern int foo;             \ 
    int bar = foo;              \ 
    if (condition) {             \ 
    Bar_Foo();              \ 
    }                 \ 

#define Foo_Bar2()             \ 
    if (condibar != footion1){           \ 
    AbortAsyncIOCB(aiocb);           \ 
    return;               \ 
    }                 \ 
    if (condition) {             \ 
    Bar_Foo();              \ 
    }                 \ 
} 

keine weiteren Header enthalten sind, so anders als das letzte Makro suchen seltsam, ich konnte keine offensichtlichen Fehler finden. Ich benutze Cygwin und ich bin ziemlich ahnungslos.

+0

Kann eine statische Funktion in einer anderen Funktion deklariert werden? –

+0

Ich kenne nicht den genauen Weg, aber die Leute sagen, es kann http://stackoverflow.com/a/11706921/2792852 – feos

+0

OK ... und warum? –

Antwort

4

Sie können keine statische Funktion innerhalb einer anderen deklarieren. Sie müssen die Deklaration außerhalb von void(x) setzen:

#define ASYNC_FUNCTION(x)            \ 
static void internal ## x (ASYNCIOCB *);        \ 
void x(void) {               \ 
    ASYNCIOCB *aiocb = AcquireAsyncIOCB();        \ 
    CallAsyncNativeFunction_md(aiocb, internal ## x);     \ 
}                  \ 
static void internal ## x (ASYNCIOCB *aiocb) 

Dann, wenn Sie die Quelle über den Präprozessor über gcc -E laufen, können Sie so etwas wie dieses (extra Abstand hinzugefügt) erhalten werden:

static void internalOccasional_function_name (ASYNCIOCB *); 
void Occasional_function_name(void) 
{ 
    ASYNCIOCB *aiocb = AcquireAsyncIOCB(); 
    CallAsyncNativeFunction_md(aiocb, internalOccasional_function_name); 
} 
static void internalOccasional_function_name (ASYNCIOCB *aiocb) 
{ 
    { 
     int a=1; 
    } 
    ASYNC_resumeThread(); 
} 
+0

Ich frage mich immer noch, wie es mit cl kompiliert wurde (und für den Autor dieses Codes). – feos

+1

"Sie können keine Funktion innerhalb eines anderen deklarieren". Äh ... Ja, das kannst du natürlich. Warum nicht? Nur die 'statische' Funktionsdeklaration ist nicht erlaubt. – AnT

+0

@AnT danke für die Klarstellung. Bearbeitet. – dbush

1

In C-Sprache können lokale Funktionsdeklarationen optional Speicherklassenspezifizierer extern enthalten. Dies ist der einzige Speicherklassenspezifizierer, den eine lokale Funktionsdeklaration haben kann. Andere Speicherklassenspezifizierer sind nicht zulässig.

6.7.1/7:

Die Deklaration eines Bezeichners für eine Funktion, die Umfang hat blockieren soll außer extern keine explizite Speicherklassen Spezifizierer aufweisen.

+0

* Hinweis, einige Kernel-Implementierungen verletzen Standard (geschrieben vor Standard, ich denke), d. H. Static__exittest() in Makro module_exit (exit) in module.h – Error

Verwandte Themen