Velocity Reviews > explain the code snippet

explain the code snippet

Ajinkya
Guest
Posts: n/a

 05-11-2007
int main()
{
struct num {
int x,y;
} val[4] = {1,1,2,3,4,5,6,7};
struct num *ptr = val;
int i=0;
for(;i<4;i++) {
ptr->x = ptr->y, ++ptr++->y;
printf("%d,%d ", val[i].x, val[i].y);
}
}

What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

AK

Eric Sosman
Guest
Posts: n/a

 05-11-2007
Ajinkya wrote On 05/11/07 13:34,:
> int main()
> {
> struct num {
> int x,y;
> } val[4] = {1,1,2,3,4,5,6,7};
> struct num *ptr = val;
> int i=0;
> for(;i<4;i++) {
> ptr->x = ptr->y, ++ptr++->y;
> printf("%d,%d ", val[i].x, val[i].y);
> }
> }
>
> What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

It confuses people. Look up "comma operator" in

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

Ajinkya
Guest
Posts: n/a

 05-11-2007
On May 11, 11:20 am, Eric Sosman <(E-Mail Removed)> wrote:
> Ajinkya wrote On 05/11/07 13:34,:
>
> > int main()
> > {
> > struct num {
> > int x,y;
> > } val[4] = {1,1,2,3,4,5,6,7};
> > struct num *ptr = val;
> > int i=0;
> > for(;i<4;i++) {
> > ptr->x = ptr->y, ++ptr++->y;
> > printf("%d,%d ", val[i].x, val[i].y);
> > }
> > }

>
> > What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

>
> It confuses people. Look up "comma operator" in
> your C textbook or reference.

Sorry sir, very trivial question. I got the answer before anyone
posted so sorry to disturb you all.
>
> --
> (E-Mail Removed)

Bill Lee
Guest
Posts: n/a

 05-11-2007
On Fri, 11 May 2007 10:34:29 -0700, Ajinkya wrote:

> int main()
> {
> struct num {
> int x,y;
> } val[4] = {1,1,2,3,4,5,6,7};
> struct num *ptr = val;
> int i=0;
> for(;i<4;i++) {
> ptr->x = ptr->y, ++ptr++->y;
> printf("%d,%d ", val[i].x, val[i].y);
> }
> }
>
> What does "," do in ptr->x = ptr->y, ++ptr++->y; ?
>
> AK

I guess this program is demonstrating operator priorities.
It shows
1.-> have higher priority than ++, so
++ptr++->y
means:
++(ptr->y);
ptr++;
2. , have the lowest priority. So the effect of
ptr->x = ptr->y,++ptr++->y;
equals to
ptr->x = ptr->y;
++ptr++->y;
Though internally, they are different.

Richard Heathfield
Guest
Posts: n/a

 05-11-2007
Ajinkya said:

> int main()
> {
> struct num {
> int x,y;
> } val[4] = {1,1,2,3,4,5,6,7};
> struct num *ptr = val;
> int i=0;
> for(;i<4;i++) {
> ptr->x = ptr->y, ++ptr++->y;
> printf("%d,%d ", val[i].x, val[i].y);
> }
> }
>
> What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

See K&R2, page 264, in between "coercion" and "command-line arguments".

Note that the behaviour of the program is undefined.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.

Chris Torek
Guest
Posts: n/a

 05-12-2007
>Ajinkya wrote:
[given suitable items, which I snipped, and]
>> ptr->x = ptr->y, ++ptr++->y;
>> What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

In article <(E-Mail Removed)>
CBFalconer <(E-Mail Removed)> wrote:
>It discards the previous expression (ptr->y) ...

Actually, since the binding of "," is done very late, the previous
expression is "ptr->x = ptr->y".

>and evaluates the next (suspicious) one, (++ptr++->y).

Right.

This one binds as ++((ptr++)->y), from which it should be clear
how to interpret it:

Remember that "a++", for some object a, fetches the value stored
in a, adds 1 to that, schedules the new value to be put back into
the object by the next sequence point, and produces (as the value
of the postfix-++ operator) the old value of the object. So
"ptr++" means "the value that was in ptr before it gets
incremented, although the increment may happen right away, or
not, at the whim of the compiler."

In "expr->member", the expression on the left is evaluated. It
must have type "pointer to struct" (or "pointer to union"), and
the structure (or union) in question must have the named member.
The result of such an expression is named member-object.

Finally "++b", for some object b, is much like "a++", except
that the value produced by the prefix-++ operator is the new
value that will be stored into b. This value is produced whether
or not b is actually incremented at that point; all you get is
the promise that the increment will occur by the next sequence
point.

The whole thing is generally bad form since a reader must sit down
and puzzle out the individual object-modifications, making sure
that no two are applied to the same object without an intervening
sequence point. It is much clearer if one writes:

ptr->x = ptr->y;
ptr->y++;
ptr++;

although I would not be unhappy with the shorter:

ptr->x = ptr->y++;
ptr++;

myself. (This squeezes two separate side effects -- modifying both
ptr->x and ptr->y -- into a single statement, but it seems clear
that ptr->x and ptr->y are distinct objects. Of course, "seeming
clear" and "being the case" are not always identical: perhaps
earlier someone did "#define x y", or "ptr" points to a union
containing "int x; double y;". However, the union trick would give
undefined behavior even with the three-statement version.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
Reading email is like searching for food in the garbage, thanks to spammers.

Army1987
Guest
Posts: n/a

 05-12-2007

"Richard Heathfield" <(E-Mail Removed)> ha scritto nel messaggio
news(E-Mail Removed)...
> Ajinkya said:
>
>> int main()
>> {
>> struct num {
>> int x,y;
>> } val[4] = {1,1,2,3,4,5,6,7};
>> struct num *ptr = val;
>> int i=0;
>> for(;i<4;i++) {
>> ptr->x = ptr->y, ++ptr++->y;
>> printf("%d,%d ", val[i].x, val[i].y);
>> }
>> }
>>
>> What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

>
> See K&R2, page 264, in between "coercion" and "command-line arguments".
>
> Note that the behaviour of the program is undefined.

Why? ++ptr++->y means ++((ptr++)->y) which is perfectly defined.
printf returns an int, so at least in C90 omitting its declaration
is allowed (though I can't see any reason to do that). And at the
end prt points to val[4], which is allowed as long as that pointer
isn't dereferenced. The problem is that main doesn't return, and
that output doesn't end with \n?
In C99, if we #include <stdio.h> and add putchar('\n'); at the end of the
block of main this program is legal, however ugly it is.
In C90 if we add putchar('\n'); return 0; at the end the program is
legal, isn't it?
(Correct me if I'm wrong.)

Richard Heathfield
Guest
Posts: n/a

 05-12-2007
Army1987 said:

>
> "Richard Heathfield" <(E-Mail Removed)> ha scritto nel messaggio
> news(E-Mail Removed)...

<snip>

>> Note that the behaviour of the program is undefined.

>
> Why? ++ptr++->y means ++((ptr++)->y) which is perfectly defined.

I was not referring to that statement. I was referring to the behaviour
of the program, which is indeed undefined. This is because the program
calls a variadic function without a valid prototype in scope.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.

Chris Dollin
Guest
Posts: n/a

 05-14-2007
Eric Sosman wrote:

> Ajinkya wrote On 05/11/07 13:34,:
>> int main()
>> {
>> struct num {
>> int x,y;
>> } val[4] = {1,1,2,3,4,5,6,7};
>> struct num *ptr = val;
>> int i=0;
>> for(;i<4;i++) {
>> ptr->x = ptr->y, ++ptr++->y;
>> printf("%d,%d ", val[i].x, val[i].y);
>> }
>> }
>>
>> What does "," do in ptr->x = ptr->y, ++ptr++->y; ?

>
> It confuses people.

/Some/ people ... It's just like ";", but inside an expression.

It's the `++ptr++->y` that has the potential for confusion, I'd've
thought. I'd unpack it somewhat:

ptr->x = ptr->y, ptr->y += 1, ptr += 1;

Although (like Chris Torek elsethread, I see) I'd not be unhappy
to collapse the first two together:

ptr->x = ptr->y++, ptr += 1;

Note that my personal religion doesn't use `++` when the result
value is irrelevant, hence `ptr += 1` rather than `ptr++`, but
if you'd prefer the `++` then that's OK too.

> Look up "comma operator" in your C textbook or reference.

Indeed. (And note that the comma operator is /not/ what separates
arguments to functions.)

--
Scoring, bah. If I want scoring I'll go play /Age of Steam/.

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England