5

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Chris Lutz
  • 73,191
  • 16
  • 130
  • 183

2 Answers2

11

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
  • 90,079
  • 9
  • 98
  • 150
  • 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 Oct 31 '10 at 02:57
  • 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 Oct 31 '10 at 03:02
  • I would hate to see `putc()` defined that way. That path can only lead to madness. – Chris Lutz Oct 31 '10 at 03:05
  • 1
    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.. GitHub STOP HELPING ICE Oct 31 '10 at 05:06
-5

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
  • 2,642
  • 20
  • 18
  • 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 Oct 31 '10 at 03:04
  • For what reason did one moderate my answwer down? That is prety unfair! After all I did not claim IT IS LIKE THIS, but gave my "thoughts" and thinking process. Sigh ... – Angel O'Sphere Nov 03 '10 at 17:55
  • 1
    probably because "Various C and C++ standards keep that undefined" is objectively false, not a subjective statement. – Ben Voigt Dec 06 '10 at 03:10