|
Boost : |
Subject: Re: [boost] [variant2] Andrzej's review -- design
From: Rainer Deyke (rainerd_at_[hidden])
Date: 2019-04-07 08:38:14
On 06.04.19 21:24, Emil Dotchevski via Boost wrote:
> I get what you're saying, that if an assignment fails, logically you wish
> to treat the resulting state something like an uninitialized state. The
> problem is that your program can no longer assume that all objects it works
> with are valid -- that is, RAII is out the window -- except if the special
> state is (by definition) a valid state. But this contradicts your wish,
> because a valid state is nothing like an uninitialized state. It has to be
> on your mind all the time, because now objects in this state are valid (by
> definition) and you must define behavior for functions that are handed such
> objects.
You keep using the term "valid" as if its a clear-cut binary
distinction. However, I can think of at least four different degrees of
validity:
1: Garbage. A variable (of a class type) was not properly constructed
and contains complete garbage. It is undefined behavior to perform any
operation on the object, including assignment and destruction.
2: Uninitialized. A variable (of a built-in type) is uninitialized. It
is undefined behavior to read the value of this variable, but the
variable is "valid" in the sense that you can assign a new value to it
and that you can destruct it.
3: Indeterminate. A variable (of a class type) has an indeterminate,
semantically meaningless state (after throwing an exception from a
member function with the basic exception guarantee, or after being
pulled from an object pool). It is technically allowed by not
semantically meaningful to read the value of this variable, but the
variable is "valid" in the sense that you can assign a new value to it
and that you can destruct it.
4: Correct. A variable (of any type) is valid and contains a
semantically meaningful and correct value.
You seem to categorize degrees 3 and 4 as "valid" and degrees 1 and 2 as
"invalid". I'm saying that the distinction between degrees 1 and 2 is
huge, as is the distinction between degrees 3 and 4, but the distinction
between 2 and 3 is relatively small. At the physical level, there is no
distinction between degrees 2 and 3, since reading from uninitialized
memory doesn't cause any actual problems on actual hardware. At the
high conceptual level, there is also no distinction between degrees 2
and 3, because the same set of operations is semantically meaningful for
both. The distinction still exists, technically, but I consider any
code that takes advantage of this distinction suspect, and I'd love for
static code analysis tools to give the same diagnostics for degree 3 as
for degree 2. If they cannot, then that's a problem with the tools, not
with the idea.
-- Rainer Deyke (rainerd_at_[hidden])
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk