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
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
#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> |
+-------------------------+--------------------+-----------------------------+
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.
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.
> 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
[...]
> (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.
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
The common idiom i = j = k = 0; is not a problem.
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.
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> |
+-------------------------+--------------------+-----------------------------+
[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.
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.
> 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