In said:
...and provided that the function is actually errno-setting; otherwise
it's meaningless again, which makes portable programming very hard.
I have very bad feelings about errno:
errno = 0;
if (!fopen(..))
#if fopen_is_errno_setting
perror("fopen()");
#else
fputs("fopen() failed\n", stderr);
#endif
It's a quality of implementation issue. A good implementation of a
standard library function either sets errno to a meaningful value
upon failure or preserves its value. So, my approach is likely to work
quite well, even if the standard doesn't guarantee it.
If you don't want to rely on it, you're restricted to the two errno
values of C89 or three errno values of C99 and you won't be able to tell
the user why fopen() failed, because you have no portable way of telling
whether fopen sets errno to meaningful values or not.
I think it's not entirely correct (non-)analogy. fopen() always returns
NULL when it fails, so we do know an error situation has arisen, but
errno can give us more information on the *nature* of the error. getc()
returns NULL on error or on end-of-file (which I don't consider an error
condition, but tastes may vary), and ferror() can distinguish between
the two. But here we don't have any information as to the nature of
the error, because getc() does not set errno.
Huh? There are exactly two things that can go wrong: an I/O error and
an eof condition. Neither the programmer nor the user needs to know more
than that.
Is it a good idea for a user function to communicate its own errors
through errno? Could additional E.. macros from errno.h have negative
values (the Std doesn't seem to restrict this, but I haven't met a
system where this would be true)?
Macros that begin with E and a digit or E and an uppercase letter are in
the implementation name space and can't be defined by portable programs.
And errno itself, without perror and strerror is not of much use to the
application programmer. For other libraries, it's much safer to
replace errno by lib_errno and provide lib_perror and lib_strerror.
The issue was discussed, at great length, 1 year or 18 months ago, in the
context of the comp.lang.c library project. The project died when its
main advocates realised that they can't do as much as they intended
within the constraints of the C standard (mainly, they felt that a library
that is not thread-safe is not of much use to them and thread-safety
cannot be achieved in portable C code).
Dan