6

When I'm reading the C++ standard, it seems that the following code is perfectly fine according to the standard.

int main() {
   goto lol;
   {
      int x;
lol:
      cout << x << endl;
   }
}

// OK

[n3290: 6.7/3]: It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer.

Why should it work? Isn't it still dangerous to jump over its definition and use undefined x? And why should the existence of an initializer make any difference?

Eric Z
  • 14,327
  • 7
  • 45
  • 69

2 Answers2

7

You'd use an uninitialized x anyways, since int x; is as uninitialized as it's going to get. The existence of an initializer makes of course a difference, because you'd be skipping it. int x = 5; for example initializes x, so it would make a difference if you jumped over it or not.

Xeo
  • 129,499
  • 52
  • 291
  • 397
  • But the problem is, regardless there is an initializer, x is not defined because its definition is bypassed anyway. Isn't it? – Eric Z Dec 16 '11 at 03:38
  • @EricZ: The definition still occurs. `goto` is a runtime thing, it only skips runtime behavior, like initialization. – GManNickG Dec 16 '11 at 03:40
2

Isn't it still dangerous to jump over its definition and use uninitialized x?

But x would be uninitialized anyway, because it was declared without an initializer! So the goto might be skipping over assignment statements that set (sort-of-initialize) x, but it's not surprising that goto can skip over assignment statements; and the declaration itself doesn't actually do anything unless there's an initializer.

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 1
    +1 *the declaration itself doesn't actually do anything*. That's the key point. Without an initializer, no code is generated. The rules ensure that you're not actually skipping over any code. – Ernest Friedman-Hill Dec 16 '11 at 03:40
  • @Ernest, I'm curious how x is defined because its definition is passed away? – Eric Z Dec 16 '11 at 03:41
  • 2
    Imagine that a free processor register is designated to hold `x`. That's just bookkeeping in the compiler; there's nothing physically in the generated code that says "Register 17 is now `x`." Now, if `x` were initialized, we'd have code to set the register's value -- but as we said, there's none of that. – Ernest Friedman-Hill Dec 16 '11 at 03:59
  • @Ernest, Now it makes sense to me, thanks for your comments;) – Eric Z Dec 16 '11 at 04:05