* James Kanze:
[snip]
It does not happen when you return a reference from a function.
Nor when you initialize a member. On the other hand, it applies
to global references just as much as to local ones.
That's true.
[...]
Consider
void increment( unsigned& x ) { ++x; }
int main() { int y = 0; increment( unsigned(y) ); }
The cast produces an rvalue. If this compiled it would presumably
increment a temporary instead of y.
Not "If this compiled", but "When it was legal C++ and
compiled".
Sorry, that's bull. It makes no sense to talk about "valid"
(or "legal") C++ before standardization.
You're either being intentionally obtuse, or just playing
stupid.
Are you really sure you want to go that road, James?
First posting a meaningless looks-like-a-clarification, then calling
names when you're taken up on it?
First, I don't think the clarification was meaningless, because
I've consistently encountered people who misunderstood the issue
when it was presented in that way. And second, the attack is
less ad hominim than a constatation concerning one particular
statement, or way of reasoning. You statement "It makes no
sense to talk about "valid" (or "legal") C++ before
standardization" is simply ridiculous, and I know you know
better. So I have to suppose that you're making it for some
sort of rhetorical reason: being intentionally obtuse, playing
stupid (since I know you're not), or trying to provoke some sort
of reaction I can't see.
Assuming you used more than one compiler or one compiler with
more than one set of options, the languages you used were not
standard C++, and they were not one language:
they were a number of slightly different languages, conforming in
general to Bjarne Stroustup's "reference manual" for C++.
I was there, and the ARM was taken very much as a "standard".
And with the exception of g++ (which really was a different
language at the time), conformance was generally better than
conformance to the ISO standard today. (Note that the chapters
in the ARM on templates and exceptions were considered more or
less experimental, and were not treated as part of the de facto
standard.)
By (May) 1991 that reference manual had already made the
change we're discussing here.
Become a standard? Again, I was there, and there was no ISO
standard until 1998. And the text that would be the standard
didn't really stabilize until 1996-1997. Until well after the
1998, most users considered the ARM as the reference, not the
ISO standard, simply because most compilers implemented
something much closer to the ARM than to the ISO standard.
Programs using the earlier
bind-temporary-to-reference-to-non-const could still compile
and in that sense be valid (for a given compiler), for the
intention was to "fade out" use of that feature.
In 1991, yes. The rule was changed before the ARM, and by 1991,
the ARM was rapidly becoming the definition of what was legal
and valid C++. The rule wasn't present in earlier versions of
"The C++ Programming Language", however, which was the reference
before the ARM.
So your C++ programs written between 1991 and 1998 could get
away with being valid for the compiler(s) used, but invalid
wrt. the "reference manual", and neither valid nor invalid
wrt. to any standard, not yet existing.
A program which bound a temporary to a non-const reference
wasn't valid or legal in 1991. And all of the "up to date"
compilers at the time warned (except maybe g++: at the time, g++
was so bad you couldn't use it). But I'm not sure what your
point is. There was a standard. I evolved over time, some
compilers took more time than others to update, and most treated
the new restrictions as warnings, rather than errors, to avoid
breaking existing code. The situation hasn't really changed,
except that instead of Stroustrup himself promulgating the
standard, it is defined by ISO.
The definition of what is "valid" and "legal" C++ evolves over
time.
Look. I posted because, from experience, I know that the
overall issue needs more clarification than you gave. Everytime
someone hears that "if a temporary is bound to a reference, it's
lifetime is extended to that of the reference", they seem to
assume transitivity (which, strictly speaking, is implied in the
statement, even if it wouldn't occur to me to assume it).
At the end of the statement, I made a minor, unimportant
correction, more in fun than anything else. (Maybe I should
have put a smiley on it.) Technically, it's not "if it
compiles" (since it doesn't), but "when it compiled" (since it
once did). And you come back with this bullshit that there was
no C++ language before ISO. Which, quite frankly, sort of
surprises someone like me who was using it back then; who was
writing C++ code, and sending in error reports to the compiler
vendors for non-conformance with the language specification:
"legal" and "valid" C++ code which didn't compile, or compiled,
but did the wrong thing, and C++ code which should not have
compiled, but did. Of course, we had to contend with the fact
that not all compilers implemented all of the latest
specification (but that's the case today as well), and that some
compilers intentionally deviated in certain cases (also the case
today).
Interestingly, while the ARM cites the same rationale as I did
earlier for disallowing the non-const ref binding to
temporary, in one Usenet discussion I had with Bjarne
Stroustrup about this, he cited his sense of elegance and
unified rules for allowing temporary lifetime extension, just
one rule fit all (and in particular also fitting argument
passing).
So I think there were a number of factors influencing the decision.
As I said, the reason you cited was the reason I'd always heard.
The example you gave is, in fact, the usual example I've seen.
I'm quite convinced that it is the explination of why the change
was made. My critical comment above is limited to your
statement that you couldn't talk about "legal" and "valid" C++
before ISO intervened, when we not only could, but did.