|
Boost : |
Subject: Re: [boost] [variant2] Andrzej's review -- design
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2019-04-07 17:26:43
AMDG
On 4/7/19 2:38 AM, Rainer Deyke via Boost wrote:
> 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,
I disagree. The rules for (2) regarding construction
and destruction are a bit relaxed, but most uses are
still undefined behavior.
> 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.
The hardware behavior is irrelevant. It only applies
if you assume a simple translation from the source
to machine code. This is not a valid assumption due
to compiler optimizations.
>Â 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.
>
The distinction is in fact quite simple:
Does the expression: x.foo() have undefined
behavior according to the language. C++
itself makes no distinction between (3) and (4).
In Christ,
Steven Watanabe
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk