views:

147

answers:

2

Pretty clear in the title, I think. I'm not entirely sure on this, and I can't find a good answer via the Googles (alas, I haven't committed to the fine art of standards-fu), so I ask:

int i = x++, j = x++;

Is this defined? I am quite sure that i = x++, j = x++; as a normal statement would be undefined behavior is the comma operator, which is a sequence point and would be legal, but no source is quite clear on whether an initializer ends at the semicolon or once the next variable starts being declared, and since that's not the comma operator in use I can't find a clear answer. So either a) the comma ends the initializer, is a sequence point, and that works, or b) it doesn't. Which is it?

And to preclude, I know I should simplify the headache and just write it as:

int i = x++;
int j = x++;

And guarantee that it's defined. I'm asking more out of curiosity.

+10  A: 

The end of an initializer is a sequence point so the example in the title is legal.

The comma operator is also a sequence point so that your "normal statement" is also legal and well-defined.

The wikipedia article has a list of the C and C++ sequence points.

To follow up on a comment below, here's a demonstration of the fearsome power of the comma operator, as preserved in FreeBSD's stdio.h (under ifndef __GNUC__):

/*
 * This has been tuned to generate reasonable code on the vax using pcc.
 */
#define __sputc(c, p) \
        (--(p)->_w < 0 ? \
                (p)->_w >= (p)->_lbfsize ? \
                        (*(p)->_p = (c)), *(p)->_p != '\n' ? \
                                (int)*(p)->_p++ : \
                                __swbuf('\n', p) : \
                        __swbuf((int)(c), p) : \
                (*(p)->_p = (c), (int)*(p)->_p++))
#endif
Ben Jackson
I read the wiki article, but not closely enough to register the comma operator bit. (Cursed inconsistencies.) Anyway, GCC never issued any warnings to me and it always worked, so I kind of assumed it did.
Chris Lutz
Prior to GCC's statement-expression extension (`({ statements...; value })` the comma operator was the main way to make really complex macros (eg stdio's putc).
Ben Jackson
@Ben - I would hate to see `putc()` defined that way. That path can only lead to madness.
Chris Lutz
Not to mention, the idea that inlining that much code for every `putc` is better than making a simple function call is outdated by a good 10-20 years..
R..
A: 

Thats a tricky question. If you had written:

int i = 0, j = 0, x = 10;
i = x++, j = x++;

I had said: it is undefined. (Various C and C++ standards keep that undfined)

But in an initializer I'm not sure ;D ofc I had concluded it is there undefined as well, but who knows ...

Angelo

Angel O'Sphere
I was incorrect: the comma operator is a sequence point. (What would we use it for if `f(), g()` where `f()` and `g()` are both `puts(__FUNC__)` had undefined behavior?) My question still stands, but I'm led to believe you're incorrect.
Chris Lutz
-1 for incorrect answer. Comma operator is a sequence point.
R..