Re: std::max(unsigned, size_t), amd64 and C++0x
On Sep 9, 6:02? pm, David Abrahams <d...@boostpro.com> wrote:
Don't those kinds of risks occur every time you return a reference,
because it will eventually dangle? ? It's just a matter of how soon. ? The
reference to an rvalue will dangle when the rvalue is destroyed (after
the end of the full expression), while the reference to the lvalue will
dangle after the lvalue is destroyed (whenever that may be).
Because of the stack-like scoping of lifetimes, returning a reference
to an lvalue is much safer than returning a reference to an rvalue:
A& get_lvalue(A& a) {return a;}
A&& get_rvalue(A&& a) { return a;}
....
A a;
A& ar = get_lvalue(a);
....
ar ends scope
a ends scope
....
const A& car = get_rvalue(A());
temporary ends scope
....
car ends scope
If you follow simple rules such as "don't pass references to
temporaries and locals out of the scope of their referent", then you
are safe. If you break those rules (as std::min does), then you
expose your clients to dangling references.
In C++0X it is relatively easy to return a reference when it is safe
(as outlined by SG) and return a value when it is not safe to return a
reference.
C++98/03 min/max unsafely returns lvalue references to rvalues.
(period, full stop)
It seems to me that an rvalue reference to an lvalue would be a much
greater worry ;-)
<shrug> There exist safe ways to reference an lvalue with an rvalue
reference.
struct A {int data;};
std::ostream&
operator<<(std::ostream&& os, const A& a)
{
return os << a.data;
}
Now you can output your A to both rvalue and lvalue streams. No
worries.
There also exist unsafe ways to reference an lvalue with an rvalue
reference.
Just about every tool in our toolbox can be abused. The good ones are
difficult to accidently abuse. And sometimes we put up with slightly
dangerous tools because of their power, efficiency, or convenience
(comparison between signed and unsigned integral types rings a bell).
However I'm not clear on a detail: Consider a system on which long
long is the largest integral type and all other integral types are
stored with fewer bits (such as 32 bit x86). ? What is
std::common_type<int, unsigned long long>::type? ? There exists no type
on this system capable of representing the union of the ranges of int
and unsigned long long. ? My suggested amendment to your proposal is
that std::common_type<int, unsigned long long>::type should fail to
compile on this platform. ? I.e. for arithmetic types X and Y,
std::common_type<X, Y>::type results in a type that can represent all
values of X and Y /if such a type exists, else if no such type exists
a diagnostic is required/. ? Furthermore,
std::common_type<user-defined- type, X>::type would now fail to
compile unless specialized. ? This would present an inconvenience to
the author of user-defined-type for those use cases where the
conditional operator might have given satisfactory results, however
that inconvenience is offset by the correctness issue which you have
raised.
And how often would the conditional operator give correct results
anyway? ? It seems to me that it is unlikely to both compile and give a
sensible result "by chance." ? So that sounds like a good way to go.
It depends on how you define "correct". The conditional operator's
heritage comes from returning the same thing in "mixed mode" as an
arithmetic operator would return. So it usually gives the "correct"
result at least by some definition. That being said, if I were given
the task of designing the conditional operator with a clean sheet of
paper (no backwards compatibility concerns) I might be tempted to do
it slightly differently. However I have not gone through that
exercise in detail. I also might not change a thing.
In summary, basing common_type on the conditional operator was not a
random choice. The conditional operator purposefully has the
semantics that were desired for most use cases. And I'm the first to
admit that the conditional operator itself isn't perfect. But at
least it has long established, stable, well-documented behavior (for
decades now).
-Howard
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]