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?
errno_tis 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_tasint, the type of theerrnoobject isint, and all error codes areint, simply useintin your programs. It's much more portable than relying on an optional feature which is unlikely to be supported.