Boost logo

Boost :

Subject: Re: [boost] [uuid] Interface
From: Scott McMurray (me22.ca+boost_at_[hidden])
Date: 2008-12-20 22:31:39


On Sat, Dec 20, 2008 at 21:22, Vladimir Batov <batov_at_[hidden]> wrote:
>> I'd argue that pointers do have value semantics.
>
> I am not sure what to say to that.
>
>> swap(int *, int *) can only swap the pointees, not the pointers
>> themselves.
>
> In fact, swap(int* p1, int* p2) swaps the *pointers* because after the call
> p1 will have the value of p2 and p2 will have the value of p1.
>

I meant that as the declaration, not a call.

A function with signature (int *, int *) -- the only way to pass a
pointer to a function -- cannot swap the pointers, only the pointees.
To swap the pointers themselves requires a function with signature
(int *&, int*&), which is passing references-to-pointers, not
pointers.

So I consider pointers to have value semantics, and their pointees to
have a kind of reference semantics.

>> I'd say that the fundamental property of pointers is that, in the
>> relevant domain, there exists an injective map from set the "pointees"
>> to the set of pointers (the "address of" operator, for plain pointers)
>> and a surjective map from the set of pointer to the set of "pointees"
>> (the "dereference" operator, for plain pointer).
>> UUIDs fit that definition. If you label each, say, database record
>> with a UUID, there's a surjective map from the UUID to the record
>> (with something like "SELECT ... WHERE id = @id" in SQL), and an
>> injective map from the record to the UUID (by looking at the id field
>> in the record).
>
> The same concept is likely to have different meanings in different areas and
> on different absraction levels. My interpretation of a pointer is pretty
> much as Wikipedia desribes it: In computer science, a pointer is a
> programming language data type whose value refers directly to (or "points
> to") another value stored elsewhere... For me UUID does not fit *that*
> definition.
>

Ok.

If I change my argument to use "resource handle" (at a similar
abstraction level to Iterator) instead of "pointer" (where a pointer
is one kind of resource handle, as are socket handles, texture handles
in OpenGL, and many other things) do you follow what I'm trying to
say?

This is the base of my thinking about UUIDs, so I agree, we're talking
at cross purposes until I can find a way to communicate it well.

>> The point is that this is a *breaking* change in the standard unless
>> you assume that value_type() == value_type() for every type that could
>> be put in a std::vector in C++03. I can't think of any applicable type
>> that breaks that assumption -- and presumably the committee couldn't
>> either -- so I don't think that making UUID break it is a good idea.
>
> I'd appreciate if you could clarify the following for me: Is value_type() ==
> value_type() an assumption you made, or is it an assumption you know the
> committee made or the committee stated somewhere that was an expectation or
> even a requirement for not following which would be a *breaking* change?
> Could you please indicate any documents or parts of the Standard (I could
> not find anything of that kind)? And what exactly "my-style" UUID is
> breaking? These are honest questions. We've been using "my-style" UUID quite
> extensively (over a year) in our project and would like to know what exactly
> we are breaking.
>

I consider it an implied assumption by the committee, though it's not
an explicit requirement of any sort. This is based on the following 4
statements, which I consider true:

1) The committee does not like to have the semantics of well-formed
programs in one revision of the standard have different semantics in a
later revision, and as such will only make such changes if they are
unavoidable or, possibly, if they are determined to not affect any
cases of consequence.

2) In C++03, resize(sz) on a vector is defined (through a default
argument) to be equivalent to resize(sz, value_type())
[vector.capacity], so any added elements are copy-constructed from the
single default-constructed instance, so they are all equivalent (by
container element requirement on the copy constructor).

3) In n2798, the C++0x draft from the 2008-10 mailing (as well as in
previous drafts n2723 and n2588), there are 1- and 2-parameter
overloads for resize on a vector [vector.capacity], and resize(sz) is
defined, in the case where sz > size(), to "[append] sz - size()
default constructed elements to the sequence".

4) If two default-constructed instances are not equivalent, then the
change to [vector.capacity] changes the semantics of a well-formed
program.

Since this change was made to the standard and it's a relatively minor
one, my impression is that the committee believes that any value_type
where default-constructed instances are not equivalent is not a case
of any consequence.

But there are, as you mention, basically no requirements placed on
default constructors for container element types, so my conclusion
hangs on the strictness of application of statement 1 by the library
working group.

~ Scott


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