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

expression evaluation question

1 view
Skip to first unread message

Avraham

unread,
Aug 26, 2004, 3:41:49 PM8/26/04
to
Hi,

In the following program, I can not figure out why it is not an error.

int a,b,c;
int main()
{
a=b=c=3;

(a=b)=c=4; /* this is the statement in question */
/* why not error ? */

printf ("a=%d b=%d c=%d\n",a,b,c); /* prints 4 3 4 WHY ????*/

return 0;
}

I think that a=b is executed first. But then (a=b) evaluates to a VALUE.
So, it is a rvalue ! (?)
If so, how can I assign the value of c to it ?

Thank you for your help.
Niv444
--
comp.lang.c.moderated - moderation address: cl...@plethora.net

Francis Glassborow

unread,
Aug 30, 2004, 12:59:25 AM8/30/04
to
In message <clcm-2004...@plethora.net>, Avraham
<niv...@walla.co.il> writes

>Hi,
>
>In the following program, I can not figure out why it is not an error.
>
>int a,b,c;
>int main()
>{
> a=b=c=3;
>
>(a=b)=c=4; /* this is the statement in question */
> /* why not error ? */
>
> printf ("a=%d b=%d c=%d\n",a,b,c); /* prints 4 3 4 WHY ????*/
>
> return 0;
>}
>
>I think that a=b is executed first. But then (a=b) evaluates to a VALUE.
>So, it is a rvalue ! (?)
>If so, how can I assign the value of c to it ?

Did you, perchance, compile your code with a C++ compiler?


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

Kenneth Brody

unread,
Aug 30, 2004, 12:59:51 AM8/30/04
to
Avraham wrote:
[...]
Note: I inserted:

#include <stdio.h>

> int a,b,c;
> int main()
> {
> a=b=c=3;
>
> (a=b)=c=4; /* this is the statement in question */
> /* why not error ? */
>
> printf ("a=%d b=%d c=%d\n",a,b,c); /* prints 4 3 4 WHY ????*/
>
> return 0;
> }

[...]

I get the expected:

"foo.c", line 8: error: left operand must be modifiable lvalue: op "="

Are you sure that is the exact code you are compiling?

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+

Keith Thompson

unread,
Aug 30, 2004, 12:59:59 AM8/30/04
to
niv...@walla.co.il (Avraham) writes:
> In the following program, I can not figure out why it is not an error.

It is.

> int a,b,c;
> int main()
> {
> a=b=c=3;
>
> (a=b)=c=4; /* this is the statement in question */
> /* why not error ? */
>
> printf ("a=%d b=%d c=%d\n",a,b,c); /* prints 4 3 4 WHY ????*/
>
> return 0;
> }

You forgot the "#include <stdio.h>", which is required if you're going
to use printf() without invoking undefined behavior. But I don't
think that's causing the problem you're complaining about.

You're probably compiling it as a C++ program. See your compiler's
documentation to find out how to tell it what language it's compiling.
(A ".c" suffix for C vs. a ".C" or ".cpp" suffix for C++ is one common
convention.)

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Douglas A. Gwyn

unread,
Aug 30, 2004, 1:00:34 AM8/30/04
to
Avraham wrote:
> I think that a=b is executed first. But then (a=b) evaluates to a VALUE.
> So, it is a rvalue ! (?)
> If so, how can I assign the value of c to it ?

You can't assign to a non-lvalue.
Try rewriting your code, for example
a = b;
a = c = 4;
The first assignment is actually a waste of effort.

Jack Klein

unread,
Aug 30, 2004, 1:01:05 AM8/30/04
to
On 26 Aug 2004 19:41:49 GMT, niv...@walla.co.il (Avraham) wrote in
comp.lang.c.moderated:

> Hi,
>
> In the following program, I can not figure out why it is not an error.

It is a constraint violation. If your compiler did not issue a
diagnostic, your compiler is broken. Or being invoked in some
completely non-standard mode.

> int a,b,c;
> int main()
> {
> a=b=c=3;
>
> (a=b)=c=4; /* this is the statement in question */
> /* why not error ? */
>
> printf ("a=%d b=%d c=%d\n",a,b,c); /* prints 4 3 4 WHY ????*/
>
> return 0;
> }
>
> I think that a=b is executed first. But then (a=b) evaluates to a VALUE.
> So, it is a rvalue ! (?)
> If so, how can I assign the value of c to it ?

You can't, not in C. But many (perhaps even most or all) actually
compile a language of their own that resembles C by default.

> Thank you for your help.
> Niv444

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

Hans-Bernhard Broeker

unread,
Aug 30, 2004, 1:01:24 AM8/30/04
to
Avraham <niv...@walla.co.il> wrote:

[...]


> (a=b)=c=4; /* this is the statement in question */
> /* why not error ? */

> I think that a=b is executed first.

Not really. There is no rule to say which of c=4 and a=b are executed
first, in the above line. Actually, it's not even guaranteed that
either of them is executed "first" at all --- the compiler is at
liberty to intermix their execution any way it likes.

> But then (a=b) evaluates to a VALUE.

Care quoting chapter and verse to back up that statement?

> So, it is a rvalue ! (?)

Your compiler obviously thinks it's an lvalue, too.

--
Hans-Bernhard Broeker (bro...@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Michael Tiomkin

unread,
Aug 30, 2004, 1:03:24 AM8/30/04
to
niv...@walla.co.il (Avraham) wrote in message news:<clcm-2004...@plethora.net>...

> Hi,
>
> In the following program, I can not figure out why it is not an error.
>
> int a,b,c;
> int main()
> {
> a=b=c=3;
>
> (a=b)=c=4; /* this is the statement in question */
> /* why not error ? */
>
> printf ("a=%d b=%d c=%d\n",a,b,c); /* prints 4 3 4 WHY ????*/
>
> return 0;
> }
>
> I think that a=b is executed first. But then (a=b) evaluates to a VALUE.
> So, it is a rvalue ! (?)
> If so, how can I assign the value of c to it ?

Well, I think you made several mistakes in this case. First, a=b
doesn't need to execute first. The compiler can execute c=4 before.
Fortunately, in your case there will be the same result.
Second, a=b evaluates to an lvalue of 'a'. In case that an assignment
appears at the right hand side of another assignment, like c=3 in
b=c=3, only the value part is used. Recall that 'a' itself is also an
lvalue, and it can be used as a value in b=a, and as an assignment
target in a=5.

I don't think that chain assignments are useful in C, because they
can confuse somebody else who will read your code. The '=' infix
operator is right-to-left, and all the other infix operators in C are
left-to-right.
I would prefer to avoid testing the knowledge of C of somebody else
who might need to read and understand your code and make a couple of
changes very fast.
Very naturally, these patterns might be useful only in a C exam!-)

Michael

Douglas A. Gwyn

unread,
Sep 2, 2004, 2:20:40 PM9/2/04
to
Michael Tiomkin wrote:
> I don't think that chain assignments are useful in C, because they
> can confuse somebody else who will read your code.

The common idiom i = j = k = 0; is not a problem.

Keith Thompson

unread,
Sep 2, 2004, 2:21:02 PM9/2/04
to
Hans-Bernhard Broeker <bro...@physik.rwth-aachen.de> writes:
> Avraham <niv...@walla.co.il> wrote:
[...]

> > But then (a=b) evaluates to a VALUE.
>
> Care quoting chapter and verse to back up that statement?

C99 6.5.16p3:

An assignment expression has the value of the left operand after
the assignment, but is not an lvalue.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Kenneth Brody

unread,
Sep 2, 2004, 2:22:00 PM9/2/04
to
Michael Tiomkin wrote:
[...]
> > int a,b,c;
[...]

> > (a=b)=c=4; /* this is the statement in question */
> > /* why not error ? */
[...]

> Second, a=b evaluates to an lvalue of 'a'.
[...]

It does? Not on any C compiler I have access to.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+

Gene Wirchenko

unread,
Sep 2, 2004, 2:22:06 PM9/2/04
to
t...@netvision.net.il (Michael Tiomkin) wrote:

[snip]

> Well, I think you made several mistakes in this case. First, a=b
>doesn't need to execute first. The compiler can execute c=4 before.
>Fortunately, in your case there will be the same result.
>Second, a=b evaluates to an lvalue of 'a'. In case that an assignment
>appears at the right hand side of another assignment, like c=3 in
>b=c=3, only the value part is used. Recall that 'a' itself is also an
>lvalue, and it can be used as a value in b=a, and as an assignment
>target in a=5.

If so, it would mean that a is being modified twice. This
invokes undefined behaviour.

[snip]

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
I have preferences.
You have biases.
He/She has prejudices.

kgold

unread,
Sep 10, 2004, 1:15:24 AM9/10/04
to
Michael Tiomkin wrote:
> I don't think that chain assignments are useful in C, because they
> can confuse somebody else who will read your code.

I agree, for this reason, and because source level debuggers can't
easily set breakpoints on return values.

I once had to debug a program with lots of code of the style

...
return function(args);
}

and sometimes had to go up several layers before I could see what the
return code was.

Back in the days of printing terminals, there was an advantage to
putting as much code on a line as possible. Now I consider it a
nuisance.

Richard Bos

unread,
Sep 12, 2004, 6:47:56 AM9/12/04
to
"Douglas A. Gwyn" <DAG...@null.net> wrote:

> Michael Tiomkin wrote:
> > I don't think that chain assignments are useful in C, because they
> > can confuse somebody else who will read your code.
>
> The common idiom i = j = k = 0; is not a problem.

Neither is it a problem when the objects assigned to are conceptually
linked; for example,

top_margin = left_margin = right_margin = mms_to_pts(layout.margin);
bottom_margin = top_margin*3/2;

What I would _not_ recommend is something like this:

bottom_margin = (top_margin = left_margin = right_margin =
mms_to_pts(layout.margin))*3/2;

That kind of code _is_ confusing, and perhaps all too common.

Richard

0 new messages