2014-06-13 1 views
7

Voici mon mort simple code fictif:erreur: utilisation d'identificateur non déclaré 'errno_t'

#include <errno.h> 

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

Ce qui soulève étonnamment cette erreur:

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

j'ai commencé à suivre les traces: quand le compilateur voit les inclusions <...> il va d'abord regarder /usr/include où bien sûr j'ai trouvé le fichier errno.h. En fait, il a une seule ligne en elle, outre le commentaire de licence, qui est:

#include <sys/errno.h> 

Maintenant, à /usr/include/sys dans errno.h J'ai trouvé les lignes suivantes:

#include <sys/cdefs.h> 

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

Et à /usr/include/_types dans _errno_t.h J'ai trouvé ceci:

typedef int errno_t; 

il ressemble, il est là, et il est un alias du type entier, et une partie du errno.h - comme il se doit.

Alors pourquoi n'est-ce pas inclus? Pourquoi le compilateur déclenche l'erreur d'identificateur non déclaré?

Merci d'avance!


Infodesks:

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 variable macro __STDC_WANT_LIB_EXT1__ sera définie à /usr/include/sys dans cdefs.h dans les lignes suivantes:

/* 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 

MISE À JOUR:

Comme @PaulR dit dans la section commentaire: si je retire le drapeau -std=c11, il compile. Ce qui est tout aussi surprenant que l'erreur soulevée si le drapeau était inclus. Donc, j'étend cette question avec une sous-question:

Est-ce que la norme C11 ne fait pas partie de la norme C11, ou pourquoi n'est-elle pas incluse, lorsque la norme est spécifiée pour le compilateur?

+0

Incluez-vous 'cdefs.h' (directement ou via d'autres includes)? '__STDC_WANT_LIB_EXT1__' est défini sur une condition. Cette condition est-elle remplie? –

+0

@BlueMoon mis à jour le post - le '/ usr/include/sys/errno.h' a l'inclusion avant de vérifier si la var est définie ou non –

+0

C'est parce que vous compilez avec' -std = c11' - prendre cela, ou utilisez le '-std = gnu11' moins strict, et il compilera très bien. –

Répondre

20

errno_t n'est pas un type standard; il fait partie de l'annexe K, facultative (et largement détestée et non supportée), incluse avec ISO C11 seulement en raison d'un fournisseur particulier ayant l'habitude d'ignorer et de saboter la norme.

Depuis l'annexe K définit comme errno_tint, le type de l'objet errno est int, et tous les codes d'erreur sont int, utilisez simplement int dans vos programmes.C'est beaucoup plus portable que de compter sur une fonctionnalité optionnelle qui est peu susceptible d'être prise en charge.

+7

..namely MS ;-) –

+2

Donnez-leur du temps - il leur a fallu 15 ans pour se familiariser avec C99! –

+7

Le plus gros problème est qu'ils ont mis un point d'essayer d'imposer leurs ajouts inutiles à la langue dans une norme qu'ils n'ont aucun intérêt ou intention de suivre. Ce n'est pas la façon dont les normes sont censées fonctionner. Si vous ne voulez pas suivre la norme, vous ne devriez pas participer à essayer de le façonner. –

Questions connexes