Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Examples for return from assignment.

67 views
Skip to first unread message

Phil Romig

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to

I am teaching a C++ class and just covered the assignment operator.
The students were curious about why you return a reference rather than
an instance, and I gave them the standard answer "so you can chain
together expressions". Off the top of my head during lecture the best
example I could come up with is ((a = b) = c). But it was rather hard
to justify when an expression of that form would come up.

Does anyone have a nice, clean example of an expression that includes
an assignment to the results of an assignment. Keep in mind this is an
intro class. Complex or convoluted examples are usually not worth it
since they tend to confuse more than illustrate. The students are willing
to take "you just have to trust me" as an answer, but I have always felt
that somewhat unsatisfying.

thanks much
Phil

P.S. I look at the example in Cline and Lomow's C++ FAQ (a good source for
examples if you are an instructor) but all it has is:
x = y = 5;
if ((z = x) == y)

I don't see that either of these do assignment to an assignment. It does
illustrate their main point, that you should return *this, but am I missing
something?

--
+--------------------------------------------+----------------------+
| Dr. Phillip Romig | |
| Dept. of Mathematics and Computer Science | 205 Stratton |
| Colorado School of Mines | pro...@acm.org |
| Golden, CO 80401 | 303.273.3866 |
+--------------------------------------------+----------------------+

Josh Sebastian

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to
In article <m3hf7ig...@cse.Mines.EDU>,

Phil Romig <pro...@acm.org> wrote:
>
> I am teaching a C++ class and just covered the assignment operator.
> The students were curious about why you return a reference rather than
> an instance, and I gave them the standard answer "so you can chain
> together expressions". Off the top of my head during lecture the best
> example I could come up with is ((a = b) = c). But it was rather hard
> to justify when an expression of that form would come up.

(a = b) = c is 100% genuine undefined behavior. (Mike, get a tissue! ;-)

At least it is when dealing with the primitive data types. That's
because it modifies a single memory location without any intervening
sequence points.

>
> Does anyone have a nice, clean example of an expression that includes
> an assignment to the results of an assignment. Keep in mind this is an
> intro class. Complex or convoluted examples are usually not worth it
> since they tend to confuse more than illustrate. The students are
willing
> to take "you just have to trust me" as an answer, but I have always
felt
> that somewhat unsatisfying.

consider a = b = c;
This, of course, groups as a = (b = c);
This should have the same semantics as:
b = c;
a = b;

But if the operator= returns a paramter by value (rather than
reference), the semantics do not match. In particular, it is the same
as:
b = c;
a = T(b); // T is the type of a, b, and c

Notice the intervening copy-constructor and temporary object. If the
constructor somehow modifies the data (not as impossible as you would
think) or is in some other way non-trivial, then this will behave
differently from the version without the intervening copy.

Whether or not the operator= should return a reference or a const-
reference is another story, though (and one which I am unable to
answer).

_______

"Yields falsehood when preceded by its quotation" yields falsehood when
preceded by its quotation.


Sent via Deja.com http://www.deja.com/
Before you buy.

Oliver A Ruebenacker

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to
Phil Romig (pro...@acm.org) wrote:
: Off the top of my head during lecture the best

: example I could come up with is ((a = b) = c).

I would rather say a = b = c, which is equivalent to (a = (b=c)). For
this case, the assigment operator could return a value rather than a
reference, but then it would have to copy-construct a temporary object,
which might be expensive or sometimes even impossible.

: But it was rather hard


: to justify when an expression of that form would come up.

I agree.

: P.S. I look at the example in Cline and Lomow's C++ FAQ (a good source for


: examples if you are an instructor) but all it has is:
: x = y = 5;
: if ((z = x) == y)
:
: I don't see that either of these do assignment to an assignment.

Not to, but from. As above, return by value would require
copy-construction.

While I find it clear that "T&operator=(...)" is to be prefered to "T
operator=(...)", I personally would be happy if the popular way to do it
would be "void operator=(...)". I am not sure why it is not. Is (a=b=c)
more efficient that (b=c; a=c)?

More convincing, however, than above examples are in my opinion:

if(a=b)
return a=b;
h(a=b);

Obviously, they could be separated to work also with "void operator=(...)":

a=b; if(b);
a=b; return b;
a=b; h(b);

Take care
Oliver

--
-- Oliver Axel Ruebenacker Oli...@Ruebenacker.de --
-- Physics Graduate Student www.ruebenacker.de --
-- Computational Condensed Matter Theory --
-- University of Massachusetts at Amherst, USA --

Consciousness is the interface between the world outside of us and the
world inside of us.

Philip Staite

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to
Consider:

class foo {};

void bar( foo& f );

If you want to code:

foo alpha;
foo beta;
bar( alpha = beta );

Then the return of foo::operator= needs to be a reference. If it
returns an instance then you've got a temporary and you cannot pass it
via reference. (you need a const reference)

Jim Hyslop

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to
In article <39c13135$1...@oit.umass.edu>,
rueb...@yolen.oit.umass.edu (Oliver A Ruebenacker) wrote:
[snip]

> While I find it clear that "T&operator=(...)" is to be prefered to
> "T
> operator=(...)", I personally would be happy if the popular way to do
> it
> would be "void operator=(...)". I am not sure why it is not.
Whenever you write an operator function, you should strive to follow the
rule "do as the ints do". This rule helps make it clear to the
maintenance programmer exactly what the operator is expected to do. An
assignment operator that returns void breaks that rule.

--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.

Oliver A Ruebenacker

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to
Jim Hyslop (jim.h...@leitch.com) wrote:
: In article <39c13135$1...@oit.umass.edu>,

: rueb...@yolen.oit.umass.edu (Oliver A Ruebenacker) wrote:
: [snip]
: > While I find it clear that "T&operator=(...)" is to be prefered to
: > "T
: > operator=(...)", I personally would be happy if the popular way to do
: > it
: > would be "void operator=(...)". I am not sure why it is not.

: Whenever you write an operator function, you should strive to follow the
: rule "do as the ints do".

Yes, but why does the assignment for int's not return void?

Oliver A Ruebenacker

unread,
Sep 14, 2000, 3:00:00 AM9/14/00
to
Branimir Maksimovic (bm...@Eunet.yu) wrote:
: > : > would "void operator=(...)". I am not sure why it is not.

: >
: > : Whenever you write an operator function, you should strive to follow the
: > : rule "do as the ints do".
: >
: > Yes, but why does the assignment for int's not return void?
:
: In that case, how could you write following:
:
: int c=5, a , b;
:
: a=b=c;

Why not simply:

b=c; a=b;

Branimir Maksimovic

unread,
Sep 14, 2000, 9:25:14 PM9/14/00
to

"Oliver A Ruebenacker" <rueb...@wilde.oit.umass.edu> wrote in message
news:39c14a01$1...@oit.umass.edu...

> Jim Hyslop (jim.h...@leitch.com) wrote:
> : In article <39c13135$1...@oit.umass.edu>,
> : rueb...@yolen.oit.umass.edu (Oliver A Ruebenacker) wrote:
> : [snip]
> : > While I find it clear that "T&operator=(...)" is to be prefered to
> : > "T
> : > operator=(...)", I personally would be happy if the popular way to do
> : > it
> : > would be "void operator=(...)". I am not sure why it is not.

>
> : Whenever you write an operator function, you should strive to follow the
> : rule "do as the ints do".
>
> Yes, but why does the assignment for int's not return void?

In that case, how could you write following:

int c=5, a , b;

a=b=c;

Greetings, Bane.


Josh Sebastian

unread,
Sep 14, 2000, 10:09:09 PM9/14/00
to
"Oliver A Ruebenacker" <rueb...@wilde.oit.umass.edu> wrote in message
news:39c14a01$1...@oit.umass.edu...
> Jim Hyslop (jim.h...@leitch.com) wrote:
> : In article <39c13135$1...@oit.umass.edu>,
> : rueb...@yolen.oit.umass.edu (Oliver A Ruebenacker) wrote:
> : [snip]
> : > While I find it clear that "T&operator=(...)" is to be prefered to
> : > "T
> : > operator=(...)", I personally would be happy if the popular way to do
> : > it
> : > would be "void operator=(...)". I am not sure why it is not.
>
> : Whenever you write an operator function, you should strive to follow the
> : rule "do as the ints do".
>
> Yes, but why does the assignment for int's not return void?

Most languages work that way. C and its ilk just happen to allow the
programmer to express himself more freely WRT assignment statements (and a
lot of other stuff too).

________

"Yields falsehood when preceded by its quotation" yields falsehood when
preceded by its quotation.

Josh Sebastian
<cur...@earthlink.net>


Andrew Koenig

unread,
Sep 14, 2000, 11:18:14 PM9/14/00
to Philip Staite
Philip> Consider:
Philip> class foo {};

Philip> void bar( foo& f );

Philip> If you want to code:

Philip> foo alpha;
Philip> foo beta;
Philip> bar( alpha = beta );

Philip> Then the return of foo::operator= needs to be a reference. If
Philip> it returns an instance then you've got a temporary and you
Philip> cannot pass it via reference. (you need a const reference)

This example is not too far from the original example that motivated
making assignment return a reference. The original example was something
like the following:

class Foo {
public:

Foo& assign(const Foo& x) {
return (*this = x);
}
};

The person who wrote

return (*this = x);

thought it meant the same thing as

*this = x;
return *this;

Unfortunately, at the time it didn't, because = returned an rvalue
by default for C compatibility. Moreover, at the time, C++ permitted
a nonconst reference to an rvalue.

So what the compiler did was to create a temporary to hold the result
of (*this = x), copy *this into the temporary, bind a reference to the
temporary, destroy the temporary, and return the dangling reference.

It took a lot of debugging effort to find this problem.

Subsequently, we learned that

1) In C,

x = y;
return x;

is always equivalent to

return (x = y);

2) In C++ the equivalence breaks (for the default definition
of =) only if you are in the body of a function that
returns a reference.

3) If you change the definition of = to return an lvalue,
it is not possible to write a C program that detects the
change.

Therefore, the change, although it appears to break C compatibility,
actually does so in a way that only C++ programs can detect, and has
the side effect of increasing C comptability in practical programs.


And that's how the leopard got his stripes, or something.


--
Andrew Koenig, a...@research.att.com, http://www.research.att.com/info/ark

Branimir Maksimovic

unread,
Sep 15, 2000, 12:27:58 AM9/15/00
to

"Oliver A Ruebenacker" <rueb...@wilde.oit.umass.edu> wrote in message
news:39c1855a$1...@oit.umass.edu...
> Branimir Maksimovic (bm...@Eunet.yu) wrote:
> : > : > would "void operator=(...)". I am not sure why it is not.

> : >
> : > : Whenever you write an operator function, you should strive to follow
the
> : > : rule "do as the ints do".
> : >
> : > Yes, but why does the assignment for int's not return void?
> :
> : In that case, how could you write following:
> :
> : int c=5, a , b;
> :
> : a=b=c;
>
> Why not simply:
>
> b=c; a=b;

That's pretty subjective isn't it?:)
What about:
if((a=some_func_that_returns_int()) == some_int)......;

>
> Take care
> Oliver
>

Greetings, Bane.


Oliver A Ruebenacker

unread,
Sep 15, 2000, 3:00:00 AM9/15/00
to
Branimir Maksimovic (bm...@Eunet.yu) wrote:
: > : > Yes, but why does the assignment for int's not return void?
: > :
: > : In that case, how could you write following:
: > :
: > : int c=5, a , b;
: > :
: > : a=b=c;
: >
: > Why not simply:
: >
: > b=c; a=b;
:
: That's pretty subjective isn't it?:)
: What about:
: if((a=some_func_that_returns_int()) == some_int)......;

a=some_function_that_returns_int();
if(a == some_int)

The problem with a=b=c is that you have to remember, how operator=
associates, and which reference it returns, and those things you do not
need for anything else except chained assignment and such.
If you don't know, then you don't know which of the following is a=b=c
equivalent to:

a=b; b=c;
b=c; a=b;
a=b; a=c;
b=c; a=c;

I remembered that it is equivalent to (a=(b=c)), but I am still not
sure what reference is returned, so I still don't know which of the
following two:

b=c; a=b;
b=c; a=c;

I haven't found it in Stroustrup's book yet.
And does it give you anything if you type "a=b=c" other than fewer
keystrokes?

Branimir Maksimovic

unread,
Sep 15, 2000, 3:00:00 AM9/15/00
to

"Oliver A Ruebenacker" <rueb...@yolen.oit.umass.edu> wrote in message
news:39c23717$1...@oit.umass.edu...

> Branimir Maksimovic (bm...@Eunet.yu) wrote:
> : > : > Yes, but why does the assignment for int's not return void?
> : > :
> : > : In that case, how could you write following:
> : > :
> : > : int c=5, a , b;
> : > :
> : > : a=b=c;
> : >
> : > Why not simply:
> : >
> : > b=c; a=b;
> :
> : That's pretty subjective isn't it?:)
> : What about:
> : if((a=some_func_that_returns_int()) == some_int)......;
>
> a=some_function_that_returns_int();
> if(a == some_int)
>

Well, I give up with Fortran since 1987:)

> The problem with a=b=c is that you have to remember, how operator=
> associates, and which reference it returns, and those things you do not
> need for anything else except chained assignment and such.

I think that possibility to do such things in C and C++ are main reason for
their popularity.

> If you don't know, then you don't know which of the following is a=b=c
> equivalent to:
>
> a=b; b=c;
> b=c; a=b;
> a=b; a=c;
> b=c; a=c;
>
> I remembered that it is equivalent to (a=(b=c)), but I am still not
> sure what reference is returned, so I still don't know which of the
> following two:
>
> b=c; a=b;
> b=c; a=c;

That does not matter, really since all values will be same,
and if you modify 'a' twice result is undefined.
But question is:

In expression a=b+=c ; which reference is returned? b's or c's?
What result would be?


>
> I haven't found it in Stroustrup's book yet.
> And does it give you anything if you type "a=b=c" other than fewer
> keystrokes?

Fewer keystrokes means time saving, but really a=b=c, is very rarely
written. (I can't rememeber that I have ever used it in real code)

Josh Sebastian

unread,
Sep 15, 2000, 3:00:00 AM9/15/00
to
"Oliver A Ruebenacker" <rueb...@yolen.oit.umass.edu> wrote in message
news:39c23717$1...@oit.umass.edu...
> The problem with a=b=c is that you have to remember, how operator=
> associates, and which reference it returns, and those things you do not
> need for anything else except chained assignment and such.
> If you don't know, then you don't know which of the following is a=b=c
> equivalent to:
>
> a=b; b=c;
> b=c; a=b;
> a=b; a=c;
> b=c; a=c;

To paraphrase:
The problem with the operator precedence is that you have to remember which
operator comes first. If you don't know, then you don't know which of the
following
2 << 3 & 4 is equivalent to:
(2 << 3) & 4
2 << (3 & 4)


I'm sorry, Oliver, but I must insist that this is a failing on the part of
the programmer, not the language. In particular, you are not even forced to
remember this stuff. If you don't want to use chained assignment, then
don't! Likewise, if you don't want to memorize the operator precedence, use
parentheses. If it ain't broke don't fix it.

0 new messages