Boost logo

Boost :

Subject: Re: [boost] [xint] Boost.XInt formal review
From: Eric Niebler (eric_at_[hidden])
Date: 2011-03-07 08:16:34


On 3/7/2011 7:44 PM, Joel Falcou wrote:
> On 07/03/11 11:48, Christopher Jefferson wrote:
>> Also, I would expect these problems to become more serious in C++0x
>> code, because users will probably write expressions like:
>>
>> auto i = x + y;
>>
>> Which would be fine for built-in types, and introduce bugs if x or y
>> was an xint::integer, using proto.
>
> auto i = x + y; does what it need to do, build an expression type. The
> only problem will arise if x and y has a shorter life span than i, which
> is usually not the case in random code.
>
> When does it happen ? When someone do something like:
>
> auto f( X const& x) -> decltype(x+x*declval<X>())
> {
> auto that = x + x*X();
> return that;
> }
>
> In this case, problem arise as X() wont be there out of f().

... and because ...

> Note however than:
>
> auto f( X const& x) -> decltype(x+x*x)
> {
> auto that = x + x*x;
> return that;
> }
>
> do work as intended by passing along the locally constructed AST to
> build a larger one at calling site.

No, it doesn't. The intermediate temporary nodes will also be stored by
reference, and those immediately go out of scope. "that" is already
invalid when you try to return it. It's even more invalid (ok, equally
invalid) when f returns.

> Now, my guess is that const ref lifespan propagation still apply in 0x,
> so doing somethign along:
>
> auto f( X const& x) -> decltype(x+x*declval<X const>())
> {
> X const local;
> auto that = x + x*local;
> return that;
> }
>
> will surely works (more or less, untested code). And if not, there is
> the only case where some deep_copy *may* be needed.
>
> And all in all, in these particular case, i wonder if a c++0x enabled
> proto wont just be able to have rvalue-ref expression nodes that let it
> fly properly.
>
> Applying 0x logic to 03 based code is not very correct. I'll keep this
> issue in mind when we'll look at porting proto in 0x, and in 0x, proto
> will surely be a totally different beast inside.

It remains to be seen what, if anything, can be done to make expression
templates and "auto" play nicely in C++0x. But I suspect the answer is:
nothing. Joel, I'm honored by your enthusiasm for Proto, but in this
case, I think it's misplaced. For a simple value type like an infinite
precision integer, expression templates are just plain dangerous.

I could imagine a design that uses a) the small object optimization for
ints below a certain threshold, and b) a ref-counted handle/body idiom
for everything else (like xpressive's regex objects), where the body
could be either i) a simple big-int terminal or ii) a type-erased
expression template that keeps its referenced bodies alive until an
evaluation is needed, and so avoid unnecessary allocations for
intermediate expressions. It must be done such that adding two big-ints
yields a big-int. "auto i = x + y;" simply MUST work, always, though it
need not actually do any addition.

But I haven't thought it all through, so that could all be bollocks. :-)

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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