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