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 21:20:11


On 2/2/2016 1:40 AM, Rob Stewart wrote:

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

Yeah, you're right. But how rare are those contexts? I mean it's not
rare for an integer to be used as an index into an array.

If you're saying that you agree with the decision to enforce mandatory
default initialization of std::vectors, but uninitialized construction
is ok for integers because the most catastrophic consequences would
happen a lower percentage of the time, I dunno, it seems to me this
argument is a judgement call that depends on how much lower that
percentage is, and the magnitude of the real world benefits of foregoing
default initialization. Maybe someone could do a sampling of code on
github or whatever and actually measure those two factors, but until
then I guess everybody has their own estimate of which factor outweighs
the other.

But I do want to point out the potentially high cost of not knowing if
your code is deterministic. Consider some hypothetical online banking
software written in C++. And let's say that a programmer accidentally
forgot to set the value of an int before use, but just by luck the
software behaved reliably in an acceptable manner on the tested and
deployed environment. So after rigorous testing and a year or whatever
of deployment, this software can be considered to be "well-tested" in
it's deployed environment. But then let's say they want to upgrade their
servers. Maybe with a different OS or OS version. Maybe the code is
recompiled. When deployed on the new server environment, that
uninitialized integer may get initialized to a different value (or range
of values) and so you could not be so confident that it would continue
to behave the same way. So it loses a lot of it's "well-tested" status.
And that can be costly.

So ideally what I would like is for boost to provide a set of types that
when used in lieu of the regular C++ types, ensure that the code is
deterministic. Or as deterministic as possible. Because being
deterministic increases the value and effectiveness of testing.

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

Yeah, I'm not sure either. Separate classes does seem heavy. But at
least it's compile-time heavy, not run-time.

Anyway I wonder if this is all moot. Have you looked at all at the "safe
numerics" library proposed in this newsgroup? The post from Jan 20 has
links. That library seems use a template to generate classes of "safe"
integers or whatever. registered_ptr should have no problem targeting
those. I don't know how things work here, but it sounds like it's pretty
far along the acceptance process. Interestingly, looking at the comments
in their default constructor -

     constexpr explicit safe_base() {
         // this permits creating of invalid instances. This is inline
         // with C++ built-in but violates the premises of the whole library
         // choice are:
         // do nothing - violates premise of he library that all safe
objects
         // are valid
         // initialize to valid value - violates C++ behavior of types.
         // add "initialized" flag. Preserves fixes the above, but doubles
         // "overhead"
         // still pending on this.
     }

- it looks like they haven't decided on whether or not to do default
initialization yet either :)


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