Boost logo

Boost :

Subject: Re: [boost] [uuid] Interface
From: Vladimir Batov (batov_at_[hidden])
Date: 2008-12-23 19:24:16

> "Declaration without definition" is extern.

Re-read Stroustrup's 4.9 and indeed I mis-interpreted "Any declaration that
specifies a value is a definition". After close reading I see that

char ch;
int i;

which I referred to as "declarations without definition" are indeed
definitions. Should have been using something like "definition without

> I think you mean
> uninitialized, which *is* allowed in classes, if they're aggregates.
> I've already uploaded a version that does exactly that.

Yes, I meant uninitialized. And I indeed remember that "classes, if they're
aggregates" are allowed uninitialized. I am not a lawer though and I was not
writing a specification. So, I was hoping the context was understood -- I
was talking about mainstream "normal" classes and not those clearly dragged
in due to backward compatibility with C. Consequently, I omitted that fringe
(in my view and usage pattern) case.

>> Therefore, IMHO making them *look* like they behave
>> similarly to built-ins sends/enforces the wrong message/impression.
> So why not make them behave like them? I've always heard "do as the
> ints do" as the guideline for value types.

Because I do not believe we can. The distinctive difference between
built-ins and classes (well, classes which are not aggregates. Pls let me
skip mentioning that every time I say "class") is that built-ins (and class
aggregates) allow "definition without initialization" and classes do not
(well, classes which are not aggregates. Pls let me not mention that every
time I say "class"). I.e. the two below do different things and carry
different overhead:

int i; // build-in uninitialized. Kind of a place-holder
Foo foo; // class. default initialized

stream >> i;
stream >> foo;

As for "why not make them behave like them", I had that crazy idea too
dreaming why could not C++ introduce something like 'noninvariant' --
"defined uninitialized" for classes. Then,

int i; // non-initialized place-holder
Foo::noninvariant foo; // non-initialized place-holder

stream >> i;
stream >> foo;

Then, I'd think we'd reconcile built-ins and classes once and for all. That
functionality is needed as we've been using some sort of it with placement
new(). However, that might be too far-fetched (and maybe troublesome) a
dream. In the end we seem to get-by as it is. We call

Foo foo; stream >> foo;

if Foo::Foo() is acceptable or, say,

Foo foo = Foo::null(); stream >> foo;

if for whatever reason Foo::Foo() is not good/available. In uuid context it
might be

boost::uuid uuid(uuid::nil); stream >> uuid;

That seems as close as we can get to mimic built-ins behavior.

> If you allow a constructor for making the nil value (obviously I would
> like the default constructor, but a function pointer so you could do
> uuid(uuids::nil) would be fine in your way), then there's no need for
> uuid::nil() to have a loop, since it can value-initialize the member
> array (which is an aggregate) letting the compiler use the most
> efficient zeroing method it has.

I do not insist on m_uuid(uuid::nil()) initialization. I insist (well, if I
can insist on anything) on making a uuid::nil explicit. Your suggestion
looks good to me.


Boost list run by bdawes at, gregod at, cpdaniel at, john at