🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

6 total messages Started by Scott Meyers Sat, 31 Oct 1992 02:52
return type of operator=
#19
Author: Scott Meyers
Date: Sat, 31 Oct 1992 02:52
21 lines
1169 bytes
Is the return type of operator= an lvalue?  In particular, if a, b, and c
are of built-in type, is this legal?

    (a = b) = c;

I couldn't find an answer in the ARM, and cfront accepts this, while g++
rejects it.  

My goal is to determine the correct type for user-defined operator=.  If
the return type is to be an lvalue, then for a class C, the return type
should be C&.  However, if the return value is not to be an lvalue, then
op= should return a const C&.  Two years ago I thought const C& was the
right type, but since then I've become convinced that C& is better.  Now
doubt has surfaced in my mind again, and I'd like to put the matter to
rest.

Scott


-------------------------------------------------------------------------------
What do you say to a convicted felon in Providence?  "Hello, Mr. Mayor."
Re: return type of operator=
#21
Author: Bjarne Stroustrup
Date: Sat, 31 Oct 1992 13:48
22 lines
968 bytes

sdm@cs.brown.edu (Scott Meyers @ Brown University Department of Computer Science) writes

 > Is the return type of operator= an lvalue?

yes

 > In particular, if a, b, and c are of built-in type, is this legal?
 >
 >    (a = b) = c;

yes

 > I couldn't find an answer in the ARM, and cfront accepts this, while g++
 > rejects it.  

The third sentence of the first paragraph of 5.17 of the reference manual
(pg 79 of the ARM, pg 506 Of my 2nd edition):

	The result of the assignment operator is ...; the result is
	and lvalue.
Re: return type of operator=
#22
Author: Andrew Koenig
Date: Sat, 31 Oct 1992 14:10
42 lines
1673 bytes
In article <1992Oct31.025229.6520@cs.brown.edu> sdm@cs.brown.edu (Scott Meyers) writes:

> Is the return type of operator= an lvalue?  In particular, if a, b, and c
> are of built-in type, is this legal?

>     (a = b) = c;

Yes.

> My goal is to determine the correct type for user-defined operator=.  If
> the return type is to be an lvalue, then for a class C, the return type
> should be C&.

It should be C&.  The general rule is that any built-in operator that
returns one of its operands will do so as an lvalue if the operand is.
(except ?:, which yields an lvalue only if both the alternatives are
lvalues of the same type).

The thing that motivated this decision was a member function like this:

	T& T::fun() {
		// ...
		return (*this = /*some value*/);
	}

The person who wrote this thought that

	return (*this = /*some value*/);

would mean the same as

	*this = /*some value*/;
	return *this;

but in a function that returns a T&, it means the same only if = yields a T&.

This is a strict extension from C: there is no way to write a strictly
conforming C program that is capable of detecting whether = returns an
lvalue.
-- 
				--Andrew Koenig
				  ark@europa.att.com
Re: return type of operator=
#36
Author: Jim Adcock
Date: Tue, 03 Nov 1992 19:52
36 lines
2088 bytes
In article <1992Oct31.025229.6520@cs.brown.edu> sdm@cs.brown.edu (Scott Meyers) writes:
|Is the return type of operator= an lvalue?  

No.

|In particular, if a, b, and c are of built-in type, is this legal?
|
|    (a = b) = c;

No, it is an error.  If (a = b) were an lvalue the same
as "a" then "a" would be being accessed twice for modification in one
expression, which in turn is an unconstrained error.  

|I couldn't find an answer in the ARM, 

My answers are based on the ANSI-C spec, under the optimistic assumption that 
some day the ANSI/ISO-C++ spec will contain equivalently detailed language about
what kinds of errors can occur in programs, and what actions compilers
can or cannot perform as a result of those errors.

|My goal is to determine the correct type for user-defined operator=.  If
|the return type is to be an lvalue, then for a class C, the return type
|should be C&.  However, if the return value is not to be an lvalue, then
|op= should return a const C&.  Two years ago I thought const C& was the
|right type, but since then I've become convinced that C& is better.  Now
|doubt has surfaced in my mind again, and I'd like to put the matter to
|rest.

The "right" thing to do is to return a value, not a reference.  Given
the infrequent use of the implied value of an assignment operation, 
many C++ programmers are lothe to return by value.  In which case
returning a const reference might be an acceptable hack.  You might return
void instead in cases where programmers shouldn't reasonably expect
to use a side-effect value of assignment.  Don't return a non-const reference.
This would further confuse users about the illegality of modifying a
variable multiple times in one expression.
Re: return type of operator=
#39
Author: John M Davison
Date: Wed, 04 Nov 1992 05:19
50 lines
2391 bytes
In article <1992Nov03.195240.14360@microsoft.com> jimad@microsoft.com (Jim Adcock) writes:
>In article <1992Oct31.025229.6520@cs.brown.edu> sdm@cs.brown.edu (Scott Meyers) writes:
>|Is the return type of operator= an lvalue?  
>
>No.

        Jim is mistaken; the built-in types return an lvalue in C++ (except for
bit-field assignment, which I don't know about offhand).

>|In particular, if a, b, and c are of built-in type, is this legal?
>|
>|    (a = b) = c;
>
>No, it is an error.  If (a = b) were an lvalue the same
>as "a" then "a" would be being accessed twice for modification in one
>expression, which in turn is an unconstrained error.  

        It is not an error.  ((a=b)=c) is equivalent to (a=c), except for side
effects, of course.

>My answers are based on the ANSI-C spec

        In Standard C, = returns an rvalue.  In C++, = returns an lvalue.

        Stroustrup talks about this in the "Lvalues" section of "The Evolution
of C++: 1985 to 1989".  I quote:

                  "Note that the default definition of assignment of
          an X as a call of

              X& operator=(const X&)

	  makes assignment of Xs produce an lvalue.  For uniformity,
	  this rule has been extended to assignments of built-in
	  types.  By implication, +=, -=, *=, etc.  now also produce
	  lvalues.  So -- again by implication -- does prefix ++ and
	  -- (but not the postfix versions of these operators).

                  "In addition, the comma and ?: can also produce
          lvalues...."

>The "right" thing to do is to return a value, not a reference.
>...Don't return a non-const reference.

        Return a non-const reference.  C++ does it with its built-in types.


-- 
John Davison
davisonj@ecn.purdue.edu
Re: return type of operator=
#648
Author: Jim Adcock
Date: Thu, 05 Nov 1992 19:02
75 lines
3810 bytes
In article <1992Nov4.051914.25983@en.ecn.purdue.edu> davisonj@en.ecn.purdue.edu (John M Davison) writes:
|In article <1992Nov03.195240.14360@microsoft.com> jimad@microsoft.com (Jim Adcock) writes:
|>In article <1992Oct31.025229.6520@cs.brown.edu> sdm@cs.brown.edu (Scott Meyers) writes:
|>|Is the return type of operator= an lvalue?  
|>
|>No.
|
|        Jim is mistaken; the built-in types return an lvalue in C++ (except for
|bit-field assignment, which I don't know about offhand).
|
|>|In particular, if a, b, and c are of built-in type, is this legal?
|>|
|>|    (a = b) = c;
|>
|>No, it is an error.  If (a = b) were an lvalue the same
|>as "a" then "a" would be being accessed twice for modification in one
|>expression, which in turn is an unconstrained error.  
|
|        It is not an error.  ((a=b)=c) is equivalent to (a=c), except for side
|effects, of course.

I continue to disagree -- with a *tiny* retraction.  The ref manual says
that (a = b) is a *value* which is a lvalue.  The ref manual DOES NOT specify
that the lvalue is a reference to a.  Thus I continue to maintain that

((a=b)=c) 

has to either NOT modify a in the outer assignment, rather instead modifying
an unnamed temporary, or alternately a is being accessed twice in one expression
for modification, which continues to be an unconstrained error.  In either
case it is certainly NOT correct to say that ((a=b)=c) is the same as (a=c)
except for side effect.  Either ((a=b)=c) is NOT the same as (a=c) or
alternately its an unconstrained error.

|>My answers are based on the ANSI-C spec
|
|        In Standard C, = returns an rvalue.  In C++, = returns an lvalue.
|
|        Stroustrup talks about this in the "Lvalues" section of "The Evolution
|of C++: 1985 to 1989".  I quote:
|
|                  "Note that the default definition of assignment of
|          an X as a call of
|
|              X& operator=(const X&)
|
|	  makes assignment of Xs produce an lvalue.  For uniformity,
|	  this rule has been extended to assignments of built-in
|	  types.  By implication, +=, -=, *=, etc.  now also produce
|	  lvalues.  So -- again by implication -- does prefix ++ and
|	  -- (but not the postfix versions of these operators).
|
|                  "In addition, the comma and ?: can also produce
|          lvalues...."

Note in none of this did the author of one of the base documents specify
*what* object the lvalue was referring to.  By continuing *not* to make
that specification the situation remains the same as in ANSI-C where accessing
a variable more than once in an expression for modification remains
ill-defined.  You may get either or both side-effects or neither or something
else entirely.

|>The "right" thing to do is to return a value, not a reference.
|>...Don't return a non-const reference.
|
|        Return a non-const reference.  C++ does it with its built-in types.

I continue to disagree.  It is extremely unlikely that any C++ programmer
is going to use that non-const reference in a legal manner.  Do them a 
favor up front and at least make it const.  

I wonder if this whole mess shouldn't be added to the list of non-modifiable 
lvalues?  Or are these issues going to be eventually clarified by adding clear
constraints to the eventual ANSI/ISO-C++ spec?
  
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads