Boost logo

Boost :

Subject: Re: [boost] [smart_ptr] Interest in the missing smart pointer (that can target the stack)
From: Rob Stewart (rob.stewart_at_[hidden])
Date: 2016-02-02 04:40:43


On February 2, 2016 2:25:42 AM EST, Noah <duneroadrunner_at_[hidden]> wrote:
> 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.

I understand, but he was replying to something you wrote in response to my uninitialized query and I hadn't replied to that previously.

> 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)?

There are tradeoffs to those options. Consider things like no-throw new expressions and creating a lock guard that assumes ownership rather than acquiring its lock. Those use arguments to differentiate them from other uses, so there's precedent for the approach.

> 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.

You have to remember a second name either way. Once constructed, the objects will be the same or very similar in behavior.

> 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).

I see no conflict.

[snip]

> 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?

If you want that kind of control, then you want policy classes, which means different types in the end.

> 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?

Policies

> >> 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.

I didn't think otherwise.

> 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.

That's certainly possible.

> 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.

Actually, vector would be quite dangerous to use without default initialization to establish its invariants. The same can't be said for an integer, though using the garbage value might be dangerous in some contexts.

> Do you still prefer the single class with an
> extra constructor for "uninitialized construction" solution to the one
> I proposed?

It's hard to say. Adding a separate class or policy just to have the uninitialized case is heavy, but the overload may not apply to all specializations of the template.

___
Rob

(Sent from my portable computation engine)


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