|
Boost : |
From: Fernando Cacciola (fcacciola_at_[hidden])
Date: 2003-09-01 21:50:44
"Joel de Guzman" <djowel_at_[hidden]> escribió en el mensaje news:00c501c370f0$9afd2850$8ca245ca_at_godzilla...
> Fernando Cacciola <fernando_cacciola_at_[hidden]> wrote:
>
> >> variant throws throws a bad_get exception
> >> when you get a reference to a T which is not the held type. I don't see
> >> a problem why you can't do something similar.
>
> Pardon me, but you are clearly mistaken!
>
I'm clearly misphrasing it, that 's for sure.
What I mean is that for an operation that reads a value,
the value as a result is IMHO the only _meaningful_ behaviour.
So, reading a value that isn't there has undefined meaningful behaviour
as I see it, meaning that the defined behaviour of throwing an exception
is of little help to the code that tried to read it.
Let me put it another way:
why is there the concept of "undefined behaviour" at all?
Because for some operations, anything but the expected outcome is so meaingless
that we prefer to leave the exceptional case undefined than to fix an arbitrary
behaviour.
There are cases when undefined behaviour is used because a fixed fall back behaviour
may not be universally implementable, but that's not always the case.
IMO, accesing the value of an uninitialized optional is undefined behaviour
and this behaviour cannot be defined _meaningfuly_ since
throwing an exception is not really meaningful for the operation per see.
> Are you saying that variant's
> get<T>(v) leads to undefined behavior? NO!
>
I'm not saying that, don't worry :-)
I'm saying that the choice made by variant<> in this regards is to the code
using get<> as hopeless as undefined behaviour.
I don't think that preconditions (and exceptions thereof) should be used to
arbitrarily make the illusion of giving meaning to an operation that is
undefined at the conceptual level.
Trying to get the wrong kind of type from a variant, or an uninitialized value
from an optional, or a past-the-end element of an array, or a reference to an
object pointed to by a null-pointer, or a short int representation of a very huge
long double value are all conceptually undefined operations.
Defining them as core-dumps, thrown exceptions, or whatever; is
certainly useful at the overall engineering level, but the operations remain
conceptually undefined.
My argument about the Undefined Behaviour problem referred to the
conceptual meaningful behaviour of value access.
Any fall back behaviour that I might choose for engineering purposes don't
make the operation any more defined w.r.t to the expected outcome.
That is, if the value isn't there, the task trying to get it will abort whether a core dump
ocurrs or an exception is thrown.
Which one of these is, as I said, relevant at the global application level,
but not at the operation level.
So, I agree with you that some behaviour can be defined, but I prefer
to leave it undefined just as vector::front() leaves undefined an attempt to
access the first element of an empty container.
Fernando Cacciola
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk