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_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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With