问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/24206989/error-use-of-undeclared-identifier-errno-t