Re: Necessity of multi-level error propogation
On Mar 13, 2:38 pm, Jeff Schwab <j...@schwabcenter.com> wrote:
James Kanze wrote:
* Jeff Schwab:
errno isn't a global variable
It certainly behaves like one.
Not really. For example, variable names respect scopes, but
errno does not.
That's a good point. I wasn't actually thinking of that level,
of course, and had more runtime behavior in mind, but it's
certainly a significant difference.
Someone who really thinks errno is a global variable will have
a heck of a time debugging the following code:
#include <errno.h>
class errno_exception
{
int m_errno;
public:
errno_exception( int errno )
: m_errno( errno ) { }
int errno() const {
return m_errno;
}
};
In fact, the latter works in GCC 4, if and only if <errno.h>
is removed.
It works with Sun CC if you compile for single threaded:-).
As you've pointed out, though technically meaningless under
the current C++ standard, errno behaves as thread-local
storage on all modern Unixen. There is no danger that setting
errno in one thread will somehow affect a different thread.
(As with all things, some compilers apparently need a
particular set of flags before they'll do the right thing.)
What was bothering me the most was that I couldn't find this
guarantee in Posix. (But someone---I think it was you---has
since posted the reference.)
In C++. Curiously, both C and Posix also allow it to be an
indentifier with external linkage;
Whereas some versions of glibc prohibit
it.http://cr.yp.to/docs/unixport.html#errno
until recently, Posix actually required it to be declared:
extern int errno ;
That's been a known defect for at least 12
years:http://www.open-std.org/JTC1/SC22/WG15/docs/rr/9945-1/9945-1-54.htm=
l
Under Solaris, its definition depends on whether the -mt
option was given; in single threaded code, it's a global
variable, in multithreaded, it expands to (*(__errno())).
That's interesting. I wonder whether it's just for historical
reasons, or whether there are benefits. What's the global
variable called?
Well, Sun considers not breaking old code a benefit. If that
old code is mine, so do I:-). But I was using the header, like
the standards require, long before the standards were written,
so it's no skin off my back one way or the other. (On the other
hand, I've very definitely seen code with "extern int errno"
inside of a function.)
I can't find anything in any of the standards to the effect
that in multiple uses of errno (in the same thread), the
lvalue actually refers to the same int, although of course,
if this were not the case, the common sequence of setting
errno to zero, then calling a function and examining it
wouldn't work.
I recently was critiqued for doing that, and actually, I'm
glad I was. I'm convinced now that the right way to use errno
is never to set it manually; it is purely a conduit for the
standard library to give further details, once an error has
already been reported. The right way to check whether a POSIX
or C function has failed is via its return code.
If it has one. What do you do about strtol? (The real problem
here is that there is no one solution. For historical reasons,
Unix and C functions have quite a number of different ways of
reporting errors.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34