Boost logo

Boost :

Subject: Re: [boost] [interest] underlying type library
From: Julian Gonggrijp (j.gonggrijp_at_[hidden])
Date: 2011-08-22 11:20:16


Sebastian Redl wrote:

>>> Way back when, C++ did bitwise copying for the compiler generated copy
>>> operations, and was changed to member wise copying for good reason. I
>>> really don't want to go back to that world.
>> Let me reassure you that move_raw is not inherently about bitwise
>> copying; you can do exactly the same with memberwise copying but that
>> requires the author of the type to provide their own implementation.
> As far as I can tell, in fact, in Stepanov's paper move_raw has absolutely nothing to do with bitwise copying.

True. The bitwise business was entirely my own idea and Stepanov is
not to be 'blamed' for that part of my proposal. ;-)

> http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

Thank you, that was a very instructive read.

> Undefined behavior isn't just about "a very strict juridical sense" of things. Compilers are allowed to assume that UB doesn't happen. If you memcpy over a non-POD, the compiler is allowed to assume the whole branch containing the memcpy is dead code - it cannot ever be reached, because reaching it would invoke UB.

Touché! I'll have to accept that the bitwise approach is no solution
for any type at all. Could you quote the lines from the standard in
which memcpy over non-PODs is deemed undefined, just in order for me
to know the exact wording?

>> So far, it seems that those who have read Stepanov's paper are more
>> positive about the possible value of my proposal than those who didn't
>> read it. This seems to confirm that Stepanov is still better at
>> explaining the value of move_raw than I am.
> OK, here's the problem I see.
> Stepanov's approach requires quite a bit of manual interaction from the user. Not only requires it that the user defines underlying_type for types where the copy constructor isn't good enough, it also requires three separate overloads of move_raw.

Though this still seems better than overriding swap, swap_ranges,
rotate, reverse, partition, random_shuffle, sort, stable_sort,
inplace_merge, make_heap, etc.

> IIUC, your library attempts to solve this task generically, by providing an underlying type and move_raw implementations that work with all or at least most types.

Correct, this is what I hoped to achieve at first.

> [...]
> Therefore, what services can your library provide?
> - It cannot provide a perfect underlying type: it would require introspection, and such mechanisms are basically non-existent in C++. In fact, I do not see how you could provide any approximation beyond what Mathias proposed without the user effectively doing the work, but I'm interested in your approach.
> - It cannot provide a reliable, generic move_raw.

True. Anyone planning to use move_raw will have to implement it by
themselves. I think Eric Niebler was the first to suggest that a user-
defined move_raw should be the default.

By the way, don't you think that the kind of language features that
would enable perfect underlying types (i.e. true type functions) would
make a great addition to C++?

> What, then, does your library still do? I can see it offering a standard way of implementing underlying_type<>.

It could offer standard algorithms that make use of the user-defined
move_raw, although currently it only offers swap.

> That's nice, but I'd rather implement proper move construction/assignment and fix my type if it doesn't have a cheap default constructor. Boost.Move makes this possible in 03. I can see it offering a memcpy()-based move_raw for opt-in, but I don't think it's a good idea to do that. What's left?
>
> In my opinion, C++0x's move support has obsoleted the move_raw concept. Yes, there may be some types for which move_raw is more efficient, because it's expensive to bring a moved-from object into a valid state. But such types will, I believe, die out.

I disagree. Note that even if your default constructor is cheap, the
difference between move_raw and 'normal move' can still be a factor
two because only one object has to be modified instead of two.

>> The URL: http://www.stepanovpapers.com/notes.pdf
>>
> This is a very interesting paper, thank you.

Thanks to Vicente Botet for bringing it to my attention.

I'll launch a new gauge for interest tomorrow, building on what I've
learned from the discussion so far. Thanks to all participants for
their constructive remarks!

-Julian


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