explain the code snippet

A

Ajinkya

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.x, val.y);
}
}

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

AK
 
E

Eric Sosman

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.x, val.y);
}
}

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


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

Ajinkya

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.x, val.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.
 
B

Bill Lee

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.x, val.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.
 
R

Richard Heathfield

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.x, val.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.
 
C

Chris Torek

Ajinkya wrote:
[given suitable items, which I snipped, and]
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.)
 
A

Army1987

Richard Heathfield said:
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.x, val.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.)
 
R

Richard Heathfield

Army1987 said:
"Richard Heathfield" <[email protected]> ha scritto nel messaggio



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.
 
C

Chris Dollin

Eric said:
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.x, val.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.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top