18

Does int a=1, b=a++; invoke undefined behavior? There is no sequence point intervening between the initialization of a and its access and modification in the initializer for b, but as far as I can tell, initialization is not "modification" of the object; an initializer is specified to give the "initial value" of the object. Per 6.7.8 Initialization, paragraph 8:

An initializer specifies the initial value stored in an object.

and it seems reasonable to take "initial" as being sequenced before any access to the object. Has this issue been considered before, and is there an accepted interpretation?

banarun
  • 2,305
  • 2
  • 23
  • 40
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • I'd say Footnote 97 says that this is identical to `int a = 1; int b = a++;`. – Kerrek SB Apr 25 '13 at 15:50
  • @KerrekSB: Footnote 97 in what version (or draft) of the standard? Footnote numbers are much less stable than section numbers. – Keith Thompson Apr 25 '13 at 15:51
  • IIRC, in the newest versions of the standard, the concept of "sequence points" is being obsoleted. As to the footnotes, there was recently a discussion about a footnote that defined the order of processing of the declare-and-initialize construct, and that footnote is actually seems quite old and stable :) – quetzalcoatl Apr 25 '13 at 15:59
  • 1
    @quetzalcoatl AFAIK, the new C standard has been ratified, the concept of sequence points hasn't become obsolete and there is no mention of any plans regarding sequence points in section 6.11 "Future language directions". Where did you get this information from? Are you sure you're not talking about C++? – autistic Apr 25 '13 at 16:10
  • 1
    Oh my.. indeed, I meant C++. I didn't notice the C lang, or rather, I unintentionally added ++ to it.. Anyways, if you are interested also in it, then I've just finished digging through thread and found the discussions: http://stackoverflow.com/a/15248697/717732. Funny, the footnote number is the same;) Oh dear. Today's not my day.. Probably KerrekSB also meant the #97 from C++! – quetzalcoatl Apr 25 '13 at 16:17
  • In c++ this was a defect reported by me (and it didnt matter whether it appears in one or two declarations), and will be fixed for c++14. – Johannes Schaub - litb Apr 25 '13 at 16:33
  • See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343 – Johannes Schaub - litb Apr 25 '13 at 16:40
  • 1
    Is this important? `int a=2, b=2;` seems both shorter and safer. – Bo Persson Apr 25 '13 at 20:56
  • Obviously the code as written should not be used, but the concept may still apply. – R.. GitHub STOP HELPING ICE Apr 25 '13 at 21:20
  • @BoPersson: You are asking, like, "why bother about a+=x when we can then a=a+x". It is not important for it to be "important". It is allowed by the syntax, so we should be able to deduce either how it will behave or either know that's not undefined. – quetzalcoatl Apr 26 '13 at 07:34
  • 1
    @quetzalcoatl - No. If the code is so complicated that we have to discuss what the result is, **if any**, we just shouldn't use it. Especially not when there is a simpler version, like `int a=2, b=2;`, which is both shorter and obvious to everyone. [IOCCC](http://www.ioccc.org/) is sometimes slightly fun, but not important. – Bo Persson Apr 26 '13 at 10:46
  • @BoPersson: Seriously, I think you've misread the intent. You asked "is this important". I'm answering: yes, it is important, because the language permits it. It is not relevant here whether we should use it or not. Obviously, we should not use dereference-operator on a null-pointer, but the language permits it. Therefore, it is very important to (un)define what happens when you do it. Once the possibility to do so is removed from the language, then it will became truly unimportant. Let me just point out that the author explicitely asks for the standard and even used 'language-lawyer' tag.. – quetzalcoatl Apr 26 '13 at 11:03
  • The only place this might possibly come up in the real world is with a beautiful/hideous (depending on your perspective) macro used for initializers of some non-trivial object. However, lack of applicability of the construct has no bearing on the question at hand. – R.. GitHub STOP HELPING ICE Apr 26 '13 at 16:07
  • 2
    @BoPersson How much such code should be avoided is illustrated well by the fact that even you misread it: its result is the same as that of `int a = 2, b = 1;`. – Daniel Fischer Apr 27 '13 at 20:11
  • @Daniel - Oh :-} I was concerned about code intending to set `a` equal to 2 starting out with `int a = 1, ...` and didn't see the the other results of the code. So, even if it doesn't cause any undefined behavior, it is **obviously** confusing. Thanks. – Bo Persson Apr 27 '13 at 20:29

1 Answers1

24

It doesn't invoke undefined behaviour. In 6.7.6 (3), it is stated

A full declarator is a declarator that is not part of another declarator. The end of a full declarator is a sequence point.

that the end of a full declarator is a sequence point.

int a = 1, b = a++;
     //  ^ end of full declarator
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431