2014-06-13 30 views
7

Ecco il mio morto semplice codice fittizio:errore: uso di identificatore non dichiarato 'errno_t'

#include <errno.h> 

int main(void) 
{ 
    errno_t e; 
    return 0; 
} 

che solleva sorprendentemente questo errore:

main.c:5:5: error: use of undeclared identifier 'errno_t' 
    errno_t x; 
    ^

ho iniziato a seguire le tracce: quando il compilatore vede le inclusioni di <...> che guarderà prima a /usr/include dove ovviamente ho trovato il file errno.h. In realtà ha una sola riga in esso, oltre al commento di licenza, che è:

#include <sys/errno.h> 

Ora, a /usr/include/sys in errno.h ho trovato le seguenti righe:

#include <sys/cdefs.h> 

#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 
#include <sys/_types/_errno_t.h> 
#endif 

E a /usr/include/_types in _errno_t.h ho trovato questo:

typedef int errno_t; 

così sembra, è lì, ed è un alias del tipo intero, e parte della 012.354.- proprio come dovrebbe essere.

Allora perché non è incluso? Perché il compilatore solleva l'errore dell'identificatore non dichiarato?

Grazie in anticipo!


informazioni rilevanti:

Compiler: 
    Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)` 

Compiler flags: 
    -std=c11 -I/usr/include/sys -I/usr/local/include 

La variabile macro __STDC_WANT_LIB_EXT1__ verranno definite /usr/include/sys in cdefs.h nelle seguenti righe:

/* If the developer has neither requested a strict language mode nor a version 
* of POSIX, turn on functionality provided by __STDC_WANT_LIB_EXT1__ as part 
* of __DARWIN_C_FULL. 
*/ 
#if !defined(__STDC_WANT_LIB_EXT1__) && !defined(__STRICT_ANSI__) && __DARWIN_C_LEVEL >= __DARWIN_C_FULL 
#define __STDC_WANT_LIB_EXT1__ 1 
#endif 

UPDATE:

Come ha detto @PaulR nella sezione commenti: se tolgo la bandiera -std=c11, si compila. Il che è sorprendente quanto l'errore generato se la bandiera è stata inclusa. Quindi estendo questa domanda con una sotto-domanda:

Non è la errno_t parte dello standard C11, o perché non è inclusa, quando lo standard è specificato per il compilatore?

+0

Stai includendo 'cdefs.h' (direttamente o tramite altri include)? '__STDC_WANT_LIB_EXT1__' è definito su una condizione. La condizione è soddisfatta? –

+0

@BlueMoon ha aggiornato il post: "/ usr/include/sys/errno.h" ha l'inclusione prima di verificare se var è definito o meno –

+0

È perché si sta compilando con '-std = c11' - take fuori, o usare il meno stringente '-std = gnu11', e si compilerà bene. –

risposta

20

errno_t non è un tipo standard; fa parte dell'allegato K facoltativo (e ampiamente non gradito e non supportato), incluso con ISO C11 solo a causa di un particolare fornitore con una cronologia di ignorare e sabotare lo standard.

Poiché l'allegato K definisce errno_t come int, il tipo di oggetto è errnoint, e tutti i codici di errore sono int, è sufficiente utilizzare int nei vostri programmi.È molto più portatile che fare affidamento su una funzione opzionale che è improbabile che sia supportata.

+7

..namely MS ;-) –

+2

Dai loro il tempo - ci sono voluti 15 anni per fare i conti con C99! –

+7

Il problema più grande è che hanno cercato di imporre le loro inutili aggiunte alla lingua in uno standard che non hanno alcun interesse o intenzione nel seguire. Non è così che dovrebbero funzionare gli standard. Se non vuoi seguire lo standard non devi partecipare nel tentativo di modellarlo. –

Problemi correlati