Boost logo

Boost Users :

From: Yuval Ronen (ronen_yuval_at_[hidden])
Date: 2006-09-17 16:52:02


>> I'm suspicious of a design for a EventLog that seems to require a stream
>> to be useful, yet still allows a EventLog to be created without one, but
>> this seems to be contrary to the advice of a book on how to design an
>> application framework from the people who are responsible for designing
>> one of the most used APIs in existence (.NET). I respect the people in
>> that position, and for those who care about Amazon ratings, it's been
>> well received there
>> (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756/sr=8-1/qid=1158206783/ref=pd_bbs_1/104-6620534-4167149?ie=UTF8&s=books).
>>
>
> Proof by popularity? [The #1 book since Gutenberg has always been The
> Bible.]

Couldn't agree with you more here...

> But we weren't talking about uninitialized objects, we were talking
> about partial construction, which is a different matter. While the first
> two are not useable in a default state, they're not meant to ever be
> created in a *partially constructed* state. Either they're placeholders
> that are empty and useless, or they're fully assigned and useable.
>
>> In each case, there are a few operations that can legitimately be
>> performed on such objects, but many operations lead to UB. Is this
>> fundamentally different from the EventLog example? For example, replace
>> EventLog in my example with ofstream, and you have
>>
>> std::ofstream ofs;
>> ofs << "Hello World";
>>
>> Trouble ensues, just as it did in the EventLog example.
>>
>
> Each operation which is valid for the ofstream and iterator is...
> assignment? I note that neither of them has a partial constructor -
> which is still the core of the original question, yes?
>
>
>
>
> Or perhaps I misread your original poll question? I thought it was
> about partial construction, not about objects which have an unuseable
> default state.
>
> If instead it was "how do you feel about objects which have an
> unuseable default state?", then I change my answer to a shrug. After
> all, I don't use char* unless I have assigned it, and if I can't put off
> its declaration and can't assign it then I assign to 0.
>
> But that's not the same as the antipattern of partial construction.

But I don't agree with you here about the difference between "objects
with uninitialized state" and "partial construction". I believe they are
the same. As long the the constructor doesn't leave the object in 100%
constructed state, it doesn't matter if it's 0% or 50%. It's not 100%
either way. So I think the default constructor for std::ofstream and
std::container::iterator are a defect in the standard (which is
unfortunately probably too late to fix).

If an uninitialized state is desired (which is sometimes the case, no
doubt about it) then we can all thank God (and Fernando) for
Boost.Optional. The usage of optional<> is good for two reasons:

1. It formalizes the uninitialized state, making its existence obvious
to both the reader of the code (which doesn't have to look at the
documentation to see there is such a state), and to the compiler, which
can check the code for some bugs.

2. It allows to have the uninitialized state only where desired - on a
per-instance base, rather on a per-class base. This means that the class
itself can remain clean of the uninitialized state for any usage which
doesn't need it (and therefore suffers from its unwelcome existence).

You might say something like "but the standard doesn't have optional, so
it had to resolve to other means". Maybe so, but that doesn't make those
default constructor not-a-defect; it only makes the lack of
std::optional an additional defect as well as those default constructors.

Just my opinion...
Yuval


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net