14

The question title says it all: do declarations of the form int a = 0, b = a have undefined behavior?

Paul Manta
  • 30,618
  • 31
  • 128
  • 208
  • 2
    The next question would then be, does such a code row make any sense in any real-world scenario? Is there ever a reason why you would write this and not `int a=0; int b=0;`? – Lundin Mar 12 '13 at 20:42
  • @Lundin When the value of `a` is the result of a function that you don't want to execute twice, which is my case. I need two copies of this value: one to output and one that I need to modify while doing some other computations. – Paul Manta Mar 12 '13 at 20:55
  • possible duplicate of [Is the comma in a variable list a sequence point?](http://stackoverflow.com/questions/6414030/is-the-comma-in-a-variable-list-a-sequence-point) and [Is the order of assingment in a list of initialized variables undefined?](http://stackoverflow.com/questions/12729962/is-the-order-of-assingment-in-a-list-of-initialized-variables-undefined?lq=1)... – Jesse Good Mar 12 '13 at 21:49
  • @PaulManta What's wrong with `int a = func(); int b = a;`? – Lundin Mar 13 '13 at 07:27
  • @Lundin Nothing. But I was curious about the behavior of the other declaration. – Paul Manta Mar 13 '13 at 07:55

2 Answers2

13

No, this is well-defined. This is a declaration with two declarators, a and b. Each declarator has an initializer.

Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.

That is, the line is treated like:

int a = 0;
int b = a;
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 4
    "analyzed separately" doesn't seem to indicated anything about sequencing at execution statement. Is there a stronger indication about this in the standard? – CB Bailey Mar 12 '13 at 20:44
  • To answer my own comment, I think you need to quote 1.9/14 about the evaluation of full expressions being sequenced before the evaluation of subsequent full expressions. See comment to http://stackoverflow.com/a/6414247/19563. – CB Bailey Mar 12 '13 at 20:50
8

No, there is no Undefined Behavior.

Per Paragraph 8/3 of the C++11 Standard:

Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself

Also, as footnote 97 specifies:

A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator. That is

T D1, D2, ... Dn;

is usually(*) equivalent to

T D1; T D2; ... T Dn;

This means that a is initialized first, then b is initialized and assumes the value of a. Also notice that even if this was not the case, there has been quite a long debate on SO over whether this would or would not be UB, and some consensus has been reached on this not being UB.


(*): As explained by Olaf Dietsche in the comments, the situations where this equivalence does not hold are mentioned later on in the same footnote.

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • Footnotes are not normative in ISO standard, so they don't specify anything at all, they are just informative text. – Lundin Mar 12 '13 at 20:43
  • In addition to what Lundin said, the word "usually" doesn't give me any warm fuzzy feelings about sequence guarantees. – IronMensan Mar 12 '13 at 20:45
  • 1
    @Lundin: Footnotes are not normative, that's right. But they are often there to state things that you could otherwise infer from the Standard through more complex formal deductions. I was not able to carry out those deductions myself, but I thought this could be a relevant reference, at least as a declaration of intent. – Andy Prowl Mar 12 '13 at 20:46
  • @IronMensan The exceptions are stated in the same footnote and involve constructs reusing names `struct S ...; S S, T;` or using `auto i = 1, j = 2.0;` – Olaf Dietsche Mar 12 '13 at 20:55