In c according to spec
§6.8.1 Labeled Statements:
labeled-statement:
    identifier : statement
    case constant-expression : statement
    default : statement
In c there is no clause that allows for a "labeled declaration". Do this and it will work:
#include <stdio.h>
int main()
{
    printf("Hello 123\n");
    goto lab;
    printf("Bye\n");
lab: 
    {//-------------------------------
        int a = 10;//                 | Scope
        printf("%d\n",a);//           |Unknown - adding a semi colon after the label will have a similar effect
    }//-------------------------------
}
A label makes the compiler interpret the label as a jump directly to the label. You will have similar problems int this kind of code as well:
switch (i)
{   
   case 1:  
       // This will NOT work as well
       int a = 10;  
       break;
   case 2:  
       break;
}
Again just add a scope block ({ }) and it would work:
switch (i)
{   
   case 1:  
   // This will work 
   {//-------------------------------
       int a = 10;//                 | Scoping
       break;//                      | Solves the issue here as well
   }//-------------------------------
   case 2:  
       break;
}