Topic: 8.4.3 -- references & non-lvalue
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 14 Dec 1993 13:13:55 GMT Raw View
jamshid@ses.com (Jamshid Afshar) writes:
>Fergus Henderson <fjh@munta.cs.mu.OZ.AU> wrote:
>>> void AA (A&);
>>> AA(f()); // legal?
>>
>>No. ARM 13.2
>
>Right, but I would quote 8.4.3 as the reason f() is an unacceptable
>argument to AA(): "If the initializer for a reference to type T is an
>LVALUE of type T ..., the reference will refer to the initializer;..."
Yes, but as the original poster pointed out, this leaves unsaid
what happens if the initializer isn't an lvalue.
>> A& a = f();
>
>I always thought it was clear that such an initialization is
>an error.
I agree, and so does my compiler, but ARM 8.4.3 doesn't say it.
I don't have any doubt about the intent, but I think that the
wording should be improved.
>I do concede that 8.4.3 could be more clear. Maybe "A reference to
>type T may only be initialized by an lvalue of type T or by an object
>when can be converted to an lvalue of type T [see footnote]".
Yes, that would be fine, IMHO.
--
Fergus Henderson fjh@munta.cs.mu.OZ.AU
Author: jamshid@ses.com (Jamshid Afshar)
Date: Sun, 12 Dec 1993 08:02:19 GMT Raw View
In article <9334515.16500@mulga.cs.mu.oz.au>,
Fergus Henderson <fjh@munta.cs.mu.OZ.AU> wrote:
>> void AA (A&);
>> A f ();
>> void test() {
>> AA(f()); // legal?
>> }
>
>No. ARM 13.2:
>
> "A temporary variable is needed for a formal argument of type T&
> if the actual argument is not an lvalue ... This does not affect
> argument matching. It may however, affect the legality of the
> resulting match since a temporary may not be used to initialize
> a non-const reference."
Right, but I would quote 8.4.3 as the reason f() is an unacceptable
argument to AA(): "If the initializer for a reference to type T is an
LVALUE of type T ..., the reference will refer to the initializer;..."
That's the "main" section stating this rule; 13.2 is making a
reference to it.
>This still leaves the legality of
> A& a = f();
>in doubt.
I believe you're saying that 13.2 does not allow a temporary to
initialize a non-const reference parameter, but 8.4.3 does not
necessarily disallow this initialization in general.
I think your doubt is based on the fact that the sentence I quoted
does not explicitly say what happens when the initializer is NOT an
lvalue. I always thought it was clear that such an initialization is
an error. Note 13.2 refers to 8.4.3 immediately after "since a
temporary may not be used to initialize a non-const reference". As
I've said before, references to other sections in a piece of text
provide a lot of insight into the author's intent (which I believe is
"Like 8.4.3 says, a temporary can't be used to initialize a non-const
reference").
I do concede that 8.4.3 could be more clear. Maybe "A reference to
type T may only be initialized by an lvalue of type T or by an object
when can be converted to an lvalue of type T [see footnote]".
Apparently ANSI/ISO felt 8.4.3 could use some reinforcement with a new
example:
double& d = 2.0; // error: not an lvalue
So, I think you can be sure that:
A f();
A& a = f(); // error
is illegal.
Footnote: I did have a disagreement with a compiler writer over whether
the following is legal.
struct S { operator A&(); };
S s();
A& a = s(); // I think it's legal
He did finally agree with me that it is okay.
Jamshid Afshar
jamshid@ses.com