News for hackers. Stuff that matters.
Re:Reading a Programmer's Guide to Common Lisp by kazinator on Thursday February 22, 2024 @06:12PM (#39474641)
The point is that your goto cannot avoid this, if your local variable scopes close at the end of the function, due to not using nested blocks. If you jump around those variables, you're jumping into a region where they are still visible and not inited.

Also, my original example is invalid C++, as is yours.

C++ does not allow goto to skip variable initializations.

In C++, if you want to goto past some variable declarations, you have to do the right thing and encapsulate them into a block.

GCC's diagnostics look like:

  goto.cc: In function ‘void f()’:
  goto.cc:7:1: error: jump to label ‘end’ [-fpermissive]
   end:;
   ^~~
  goto.cc:3:8: note:   from here
     goto end;
        ^~~
  goto.cc:5:7: note:   crosses initialization of ‘int x’
     int x = 42;
         ^
Re:Reading a Programmer's Guide to Common Lisp by trealira on Thursday February 22, 2024 @06:38PM (#39474897)
> The point is that your goto cannot avoid this, if your local variable scopes close at the end of the function, due to not using nested blocks. If you jump around those variables, you're jumping into a region where they are still visible and not inited.

I see. I think I get what you're saying: if you only put variable declarations at the top of the scope, then if you only jump to labels at the same statement depth as the goto statement, you won't skip initialization or assignment of uninitialized variables. Whereas, if you mix declarations and statements, you might end up with uninitialized variables even when you only jump to labels at the same statement depth as the goto statement. Is that what you're saying, or did I grasp something orthogonal to your point?

> C++ does not allow goto to skip variable initializations.

I didn't know that until now. However, if you change the function so that x is assigned after being declared, it still compiles and produces the same result.

  void c89_fn(int arg) {
      if (arg > 0)
          goto after;
      { 
          int x;
          x = 42;
  after:
          /* x is in scope, but x could be uninitialized */
          printf("%d\n", x);
      }
  }