2011-12-29 29 views
15

Ho provato il seguente codiceÈ typedef uno specificatore della classe di memoria?

#include <stdio.h> 

int main(void) 
{ 
    typedef static int sint; 
    sint i = 10; 

    return 0; 
} 

e ha colpito il seguente errore:

error: multiple storage classes in declaration specifiers 

Quando ho fatto riferimento alla specifica C99, sono venuto a sapere che è un typedefstorage class.

6.7.1 Storage-class specifiers 

Syntax 

storage-class-specifier: 
    typedef 
    extern 
    static 
    auto 
    register 

Constraints: At most, one storage-class specifier may be 
      given in the declaration specifiers in a declaration 

Semantics: The typedef specifier is called a ‘‘storage-class specifier’’ 
      for syntactic convenience only; 

L'unica spiegazione che ho potuto trovare (sulla base di alcuni ricerca su internet e croce riferimento varie sezioni nella specifica C99) era syntactic convenience only to make the grammar simpler.

Sto cercando qualche giustificazione/spiegazione su come può un nome del tipo di avere classe di memoria specificatore?

non ha senso avere un codice come typedef static int sint;?

o Dove sto andando male ?!

risposta

14

Sì, typedef è una classe di archiviazione-specifier come l'avete trovato nella norma. In parte si tratta di una convenienza grammaticale, ma è consapevole che è possibile avere typedefo una delle più identificatori di classe di archiviazione "ovvie".

Un typedef dichiarazione crea un alias per un tipo.

In una dichiarazione static int x; il tipo di x è int. static non ha nulla a che fare con il tipo.

(Si consideri che se si prende l'indirizzo di x, &x ha tipo int*.int *y = &x; sarebbe legale come farebbe static int *z = &x ma quest'ultimo static colpisce la classe di z stoccaggio ed è indipendente della classe di x stoccaggio.)

Se qualcosa del genere fosse permesso al static non avrebbe alcun effetto in quanto non oggetto viene dichiarata . Il tipo aliasato è solo int.

typedef static int sint; 
+1

vedi: http://stackoverflow.com/questions/2218435/why-typedef-can-not-be-used-with-static – Demi

4

Forse la norma dovrebbe hanno chiamato queste cose storage-class-or-typedef-specifier e disse:

Constraints: At most, one storage-classor-typedef-specifier may be given in the declaration specifiers in a declaration

Allora non avrebbe dovuto aggiunta la nota sulla semantica.

Il commento circa la semantica sta semplicemente dicendo che typedef in realtà non controlla nulla della memoria usato per il tipo (in modo che non è semanticamente un 'identificatore di archiviazione'), ma che viene gestito sintatticamente come gli altri storage-class-specifier, e quindi non può essere utilizzato con loro.

Quindi un typedef non è in grado di determinare dove verrà memorizzata una determinata istanza di tipo, che è determinata dalla dichiarazione effettiva dell'istanza (implicitamente o esplicitamente).

Anche se quello che stai cercando sono stati consentiti, sarebbe una cattiva pratica, ne sono sicuro. Si consideri:

// in someheader.h 
typedef static int sint; 


// now in foo.c 
#include "someheader.h" 

int foo(void) 
{ 
    sint i = 10; // unless you're intimately knowledgeable about how 
        // `sint` is typedef'ed, this looks exactly like 
        // an automatic 


    // do some stuff that modifies `i`... 

    return i; 
} 

sint bar(void) // what does this mean? is `bar()` static? 
{ 
    return foo(); 
} 

Nota che è di utilizzare il preprocessore per ottenere l'effetto 'typedef statica', che renderebbe bar() una funzione statica. Quale potrebbe non essere l'effetto desiderato. Può essere.

1

Non si può fare che - almeno non con GCC di MinGW - sia all'interno che all'esterno di una funzione.

userei il preprocessore invece:

#include <stdio.h> 

#define sint static int 

int main(void) 
{ 

    sint i = 10; 

    return 0; 
} 

ottiene lo stesso risultato.

Immagino sia perché "static int" non è un tipo allo stesso modo di "volatile int".

+0

Sh00t, hai ragione. L'ho confuso con 'signed'. –

+3

Si prega di non farlo. Renderà il codice più confuso di quanto deve essere, 'sint' non sarà utilizzabile come tipo di parametro, e una funzione che restituirà' sint' avrà una proprietà che probabilmente non è intesa (collegamento interno). –

-1

typedef è sintatticamente uguale a una classe di archiviazione. Non è una classe di archiviazione. typedef è simile a #define in effetti, ma typedef è interpretato dal compilatore mentre #define è dal preprocessore. typedef può eseguire sostituzioni testuali che vanno oltre le capacità di del preprocessore.

due scopi per l'utilizzo di typedef 1. Portabilità 2. Migliore documentazione