error: use of undeclared identifier 'errno_t'

Peter Varo picture Peter Varo · Jun 13, 2014 · Viewed 25.9k times · Source

Here is my dead simple dummy code:

#include <errno.h>

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

Which surprisingly raises this error:

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

I started to follow the traces: when the compiler sees the <...> inclusions it will first look at /usr/include where of course I found errno.h file. Actually it has a single line in it, besides the license comment, which is:

#include <sys/errno.h>

Now, at /usr/include/sys in errno.h I found the following lines:

#include <sys/cdefs.h>

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

And at /usr/include/_types in _errno_t.h I found this:

typedef int errno_t;

So it looks like, it is there, and it is an alias of the integer type, and part of the errno.h -- just as it should be.

Then why isn't it included? Why the compiler raises the undeclared identifier error?

Thanks in advance!


RELEVANT INFO:

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

The macro variable __STDC_WANT_LIB_EXT1__ will be defined at /usr/include/sys in cdefs.h in the following lines:

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

As @PaulR said in the comment section: if I remove the -std=c11 flag, it compiles. Which is just as surprising as the error raised if the flag was included. So I extend this question with a sub-question:

Is not errno_t part of the C11 standard, or why isn't it included, when the standard is specified for the compiler?

Answer

R.. GitHub STOP HELPING ICE picture R.. GitHub STOP HELPING ICE · Jun 13, 2014

errno_t is not a standard type; it's part of the optional (and widely disliked and unsupported) Annex K, included with ISO C11 only because of one particular vendor with a history of ignoring and sabotaging the standard.

Since Annex K defines errno_t as int, the type of the errno object is int, and all error codes are int, simply use int in your programs. It's much more portable than relying on an optional feature which is unlikely to be supported.