Boost logo

Boost :

Subject: Re: [boost] [smart_ptr] Interest in the missing smart pointer (that can target the stack)
From: Noah (duneroadrunner_at_[hidden])
Date: 2016-02-02 02:25:42


On 2/1/2016 5:47 PM, Rob Stewart wrote:

>> I mean, is the default initialization of std::vector to the empty state
>> no
>> more correct than leaving it uninitialized? Should we require
>> programmers to explicitly set the vector state, even if they want to
>> start off with an empty vector?
>
> That's not what I asked you about. I asked if you provided a way to construct your types without initializing the data. I thought it was obvious that I was asking about a constructor overload taking an instance of, say, uninitialized_t as the mechanism. That is, one would create an instance from an argument named, say, "uninitialized."

Sorry, I'm confused. In this post I was responding to what Steve said. I
wasn't trying to respond to your question. Although I guess they're related.

And it may be my shortcoming, but it actually wasn't obvious to me that
you were asking about "a constructor overload taking an instance of,
say, uninitialized_t as the mechanism". Is that mechanism preferable to
mechanism of having separate, compatible classes I proposed (in both the
reply to Steve's post and the reply to your post)? I haven't completely
thought it through, but I might've thought that solution of having
separate types might be preferable if only for convenience reasons
because you wouldn't have to pass any arguments to get an uninitialized
variable. And, as Steve pointed out, if you choose to use a type that
requires explicit initialization before use, it may help catch some bugs
(in debug mode).

But now that you've spelled it out for me, having a single class with a
separate constructor also seems appealing because then there would
definitely be no compatibility issues between separate classes. But then
again, there may be issues other than just default initialization to
consider. For example, what if we wanted an option to disable run-time
range checking when converting between different (sized) integer types?
Keeping the one class and adding an extra constructor for that wouldn't
really work. Because you'd just be substituting one run-time check for
another, right? But another separate compatible class might work. And
how about range checking on arithmetic operations? Is that too many
options? Should we just not provide for those options?

>
>> Or is the empty state somehow
>> intrinsically valid, but the zero value for integers is not?
>
> Zero may be a valid value with semantics different than "not set." An empty vector doesn't have a magic value that means it's actually empty.

Just to be clear, I wasn't being sarcastic or anything. I'm just trying
to think this through. So I agree that zero should not be interpreted as
a "magic" value indicating "value not set". In my reply to Steve I
suggested that the integer class for example, might, in debug mode,
contain an extra bool member indicating whether or not the value had
been explicitly set. And default initialization would set that bool to
indicate that the value hadn't been explicitly set.

What I am suggesting is that, perhaps, the std::vector people decided
not to provide for uninitialized vector construction because a) they
suspected that conditional initialization would be a small portion of
all initializations and that the default empty state would be a fairly
large portion, and/or possibly b) the compiler optimizer would deal with
the redundancy in a significant portion of those conditional
initializations, and/or c) the cost of the program being
non-deterministic if a programming error slips by is unacceptably high.
(I think reason c) is the main one to most of us who desire default
initialization.) And it's not obvious to me that those reasons don't
apply to integers as well. With respect to the proportion of all
initializations that are conditional, the only way we could know that is
to do a large random sampling of code on github or whatever. I actually
googled to try and find out if anyone had done such a sampling, because
I'm actually quite curious what the answer would be. My googling was not
successful.

I know I'm not always great at expressing my ideas in writing, but if
you have time to reread my reply to Steve, in it I suggest a solution in
which three separate compatible classes would be available. Each with a
different policy for default initialization and requirement for
"explicit set before use". Do you still prefer the single class with an
extra constructor for "uninitialized construction" solution to the one I
proposed?


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk