2009-12-22 30 views
6

Ho notato un comportamento molto curioso che, se standard, sarei molto felice di sfruttare (quello che mi piacerebbe fare con esso è abbastanza complesso da spiegare e irrilevante alla domanda).Dichiarare una funzione statica e successiva non statica: è standard?

Il comportamento è:

static void name(); 
void name() { 
    /* This function is now static, even if in the declaration 
    * there is no static keyword. Tested on GCC and VS. */ 
} 

Cosa c'è di curioso è che l'inverso produce un errore di compilazione:

void name(); 
static void name() { 
    /* Illegal */ 
} 

Quindi, è questo standard e può mi aspetto altri compilatori a comportarsi nello stesso modo ? Grazie!

risposta

12

standard C++:

7.1.1/6: "A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration" [or unless it's const].

Nel primo caso, name viene dichiarato in un ambito spazio dei nomi (in particolare, il namespace globale). La prima dichiarazione modifica quindi il collegamento della seconda dichiarazione.

L'inverso è bandita perché:

7.1.1/7: "The linkages implied by successive declarations for a given entity shall agree".

Così, nel secondo esempio, la prima dichiarazione deve collegamento esterno (dalla 7.1.1/6), e la seconda ha il collegamento interno (in modo esplicito), e questi non sono d'accordo.

Chiedi anche di C, e immagino sia lo stesso genere di cose. Ma ho il libro C++ proprio qui, mentre tu sei così capace di guardare in una bozza di standard C online come sono ;-)

+0

Sto usando C++, ma ho aggiunto un tag C perché ho pensato che sarebbe stato lo stesso in C. –

+0

oh e grazie per l'ottima risposta –

3

I qualificatori che hai messo sul prototipo di funzione (o che sono impliciti) vengono usati automaticamente quando la funzione è dichiarata.

Quindi nel secondo caso la mancanza di static sul prototipo significava che la funzione era definita come NON statica, e quindi quando è stata dichiarata in seguito statica, si è trattato di un errore.

Se si dovesse omettere il tipo di ritorno nel prototipo, il valore predefinito sarebbe int e si otterrebbe nuovamente un errore con il tipo di ritorno void. La stessa cosa accade con __crtapi e __stdcall e __declspec() (nel compilatore Microsoft C).

Problemi correlati