Sequence point at comma?

F

Frederick Gotham

I know there's a sequence point at a comma, e.g.:

int main(void)
{
int a = 1;


a++, ++a, a *= 3, a <<= 4; /* Perfectly okay */
}


But does that also include the commas which separate function arguments? Is
the following code broken?

void Func( int, int, int, int );

int main(void)
{
int a = 1;

Func( a++, ++a, a *= 3, a <<= 4 );
}
 
M

Michael Mair

Frederick said:
I know there's a sequence point at a comma, e.g.:

int main(void)
{
int a = 1;


a++, ++a, a *= 3, a <<= 4; /* Perfectly okay */
}


But does that also include the commas which separate function arguments?
No.

Is
the following code broken?

void Func( int, int, int, int );

int main(void)
{
int a = 1;

Func( a++, ++a, a *= 3, a <<= 4 );
}

Yes.


Cheers
Michael
 
R

Roberto Waltman

I know there's a sequence point at a comma, e.g.:

int main(void)
{
int a = 1;


a++, ++a, a *= 3, a <<= 4; /* Perfectly okay */
}


But does that also include the commas which separate function arguments? Is
the following code broken?

void Func( int, int, int, int );

int main(void)
{
int a = 1;

Func( a++, ++a, a *= 3, a <<= 4 );
}

Yes, it is broken:

ISO/IEC 9899:1999

6.5.2.2 Function calls
Constraints
....
10 The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is
unspecified, but there is a sequence point before the actual call.
 
R

Robert Gamble

Frederick said:
I know there's a sequence point at a comma, e.g.:

int main(void)
{
int a = 1;


a++, ++a, a *= 3, a <<= 4; /* Perfectly okay */
}

Yes. Not only is there a sequence point between each operation but the
order of evaluation is guaranteed to be from left to right, the result
of which will have the type and valud of the rightmost expression.
But does that also include the commas which separate function arguments?

No, commas seperating function arguments or list items are not the
comma operator and do not introduce a sequence point.
Is the following code broken?
Yes.

void Func( int, int, int, int );

int main(void)
{
int a = 1;

Func( a++, ++a, a *= 3, a <<= 4 );
}

The function arguments may be evaluated in any order and since there is
no sequence point between the modifications of "a" the behavior is
undefined.

Robert Gamble
 
T

Tom St Denis

Frederick said:
a++, ++a, a *= 3, a <<= 4; /* Perfectly okay */

There is a difference between "it'll work" and "Perfectly okay".

Good: knowing about sequence points

Bad: Thinking the coma operator is a license to write anything.

Tom
 
K

Keith Thompson

Tom St Denis said:
There is a difference between "it'll work" and "Perfectly okay".

Good: knowing about sequence points

Bad: Thinking the coma operator is a license to write anything.

The coma operator is a license to take a very long nap.

Getting back to the comma operator ... :cool:}

The above code fragment is ok for illustrating the point. It should
not appear in actual code. A better way to write it would be:

a = ((a + 2) * 3) << 4;

More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.
 
E

ena8t8si

Keith said:
The coma operator is a license to take a very long nap.

Getting back to the comma operator ... :cool:}

The above code fragment is ok for illustrating the point. It should
not appear in actual code. A better way to write it would be:

a = ((a + 2) * 3) << 4;

More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.

The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".
 
K

Keith Thompson

Keith Thompson wrote: [...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.

The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".

If I felt the need to put those two expressions on the same line, I'd
probably write

p++; q++;
 
E

ena8t8si

Keith said:
Keith Thompson wrote: [...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.

The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".

If I felt the need to put those two expressions on the same line, I'd
probably write

p++; q++;

Yes that's another way of doing it. I usually
follow the rule of no more than one statement
on a line, which fits nicely with how comma
works in C.
 
F

Frederick Gotham

Keith Thompson posted:


If I have a very simple if-statement or loop, I might write:


if(expr) ++p,++q;

do ++p,++q;
while (expr);
 
F

Fred Kleinschmidt

Frederick Gotham said:
Keith Thompson posted:



If I have a very simple if-statement or loop, I might write:


if(expr) ++p,++q;

do ++p,++q;
while (expr);

I find those constructs to be inherently dangerous -
someone who dislikes using comma operators may
later come along and replace the commas
with semicolons, and bang! it's broken.

My personal coding standard is to ALWAYS use
braces in if, for, do, and while expressions.Even:
if (something) {return;}
 
A

Al Balmer

Keith Thompson wrote: [...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.

The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".

If I felt the need to put those two expressions on the same line, I'd
probably write

p++; q++;

Not where I've usually seen such things - as the third expression in a
for statement.
 
K

Keith Thompson

Al Balmer said:
Keith Thompson wrote: [...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.

The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".

If I felt the need to put those two expressions on the same line, I'd
probably write

p++; q++;

Not where I've usually seen such things - as the third expression in a
for statement.

Yes, that's another reasonable use for the comma operator, and one
that I forgot to mention.
 
J

Joe Wright

Keith said:
Keith Thompson wrote: [...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.
The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".

If I felt the need to put those two expressions on the same line, I'd
probably write

p++; q++;
The only place I use the comma operator is where two expressions are to
form a single statement.

char *fn = "filename";

if ((fp = fopen(fn, "r")) == NULL)
fprintf(stderr, "Can't open %s\n", fn), exit(EXIT_FAILURE);

Avoiding the comma will create two statements and cost a pair of curlies
as well.

if ((fp = fopen(fn, "r")) == NULL) {
fprintf(stderr, "Can't open %s\n", fn);
exit(EXIT_FAILURE);
}
 
P

pete

Joe said:
The only place I use the comma operator
is where two expressions are to
form a single statement.

char *fn = "filename";

if ((fp = fopen(fn, "r")) == NULL)
fprintf(stderr, "Can't open %s\n", fn), exit(EXIT_FAILURE);

Avoiding the comma will create two statements
and cost a pair of curlies as well.

if ((fp = fopen(fn, "r")) == NULL) {
fprintf(stderr, "Can't open %s\n", fn);
exit(EXIT_FAILURE);
}

I would write it the second way
without even thinking about it.

I propbably don't fully appreciate
the cost of a pair of curlies.
 
K

Keith Thompson

Joe Wright said:
Keith said:
Keith Thompson wrote: [...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.
The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".
If I felt the need to put those two expressions on the same line, I'd
probably write
p++; q++;
The only place I use the comma operator is where two expressions are
to form a single statement.

char *fn = "filename";

if ((fp = fopen(fn, "r")) == NULL)
fprintf(stderr, "Can't open %s\n", fn), exit(EXIT_FAILURE);

Avoiding the comma will create two statements and cost a pair of
curlies as well.

if ((fp = fopen(fn, "r")) == NULL) {
fprintf(stderr, "Can't open %s\n", fn);
exit(EXIT_FAILURE);
}

Yes, at the terrible expense of code that's much clearer and easier to
read.

It wouldn't even occur to me to use a comma operator in that case.
 
J

Joe Wright

Keith said:
Joe Wright said:
Keith said:
(e-mail address removed) writes:
Keith Thompson wrote:
[...]
More generally, if the subexpressions can't be combined like this,
there's no good reason to use a comma operator rather than separate
statements:

a++;
++b;
c *= 3;
d <<= 4;

*unless* the whole thing is part of a macro definition that needs to
expand to an expression rather than a sequence of statements.
The statement that "there is no good reason" is a
little strong. I expect you've seen otherwise
reasonable code that puts related assignments on the
same line, using comma operators to separate them:

p++, q++;

Depending on circumstances, it can help code clarity
to do so. cf Fred Brooks, "The Mythical Man-Month".
If I felt the need to put those two expressions on the same line, I'd
probably write
p++; q++;
The only place I use the comma operator is where two expressions are
to form a single statement.

char *fn = "filename";

if ((fp = fopen(fn, "r")) == NULL)
fprintf(stderr, "Can't open %s\n", fn), exit(EXIT_FAILURE);

Avoiding the comma will create two statements and cost a pair of
curlies as well.

if ((fp = fopen(fn, "r")) == NULL) {
fprintf(stderr, "Can't open %s\n", fn);
exit(EXIT_FAILURE);
}

Yes, at the terrible expense of code that's much clearer and easier to
read.

It wouldn't even occur to me to use a comma operator in that case.
A chacun son gout. I kinda like it. :)

Your disapproval is noted. And pete's too.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top