Dietmar said:
... you may have noticed that I'm maintaining the opinion that the
current standard already mandates setting of 'errno' in IOStreams.
I guess that, for now, I'll have to check if the compilers/libraries I
want to support (GCC, Sun CC, and MSVC++ 7 on Linux, OS X, Solaris, and
Win32, at least) set errno appropropriately and go with that.
Since there is currently no better alternative we should either
- clarify the standard to make it crystal clear that 'errno' is set
in the appropriate places in IOStreams.
- provide a "better" approach than 'errno'.
Is somebody filing a defect report on this issue? I would champion
the position that some details on the reasons of failures are
necessary in a portable way, although not necessarily by 'errno'
if there is a better alternative...
The "better alternative" would probably be to use exceptions. I'm not
particularly fond of Java's way of throwing a different type for every
possible error condition; I'd do something more like throw an
IOException, and include a enum type identifying the type of error; such
an enum would roughly correspond to all the values of errno that could
be set due to I/O operations.
However, I've never been fond of constructors throwing exceptions, as
catching them properly can do some nasty things to the structure of a
function/method in some cases. For instance, in Java (which uses
exceptions everywhere), if I wanted to open a bunch of sockets and be
able to tell which open failed, I could end up with something like this:
try {
Socket s1 = new Socket(host1, port1);
try {
Socket s2 = new Socket(host2, port2);
try {
Socket s3 = new Socket(host3, port3);
// do some socket I/O, and catch the associated exceptions
...
} catch (IOException e) {...}
} catch (IOException e) {...}
}catch (IOException e) {...}
Instead, I would prefer some mechanism such as returning an invalid
object on the failure of a constructor, having some mechanism to check
if a constructor succeeded, and throwing an exception if the invalid
object was accessed. Then, the above code would look more like this:
Socket s1 = new Socket(host1, port1);
Socket s2 = new Socket(host2, port2);
Socket s3 = new Socket(host3, port3);
if (s1.invalid()) {...}
if (s2.invalid()) {...}
if (s3.invalid()) {...}
// do some socket I/O, and catch the associated exceptions
....
Of course, this probably breaks OO badly enough to start some nice holy
wars among the purists. Does anyone have any better ideas?
Rennie