The internal or external linkage may have only variables that have a file scope.
In your first example
void init()
{
int a = 1;
}
the variable a has a block scope and hence does not have a linkage.
In the header
extern int a
there is declared a variable with external linkage that has the file scope. But it was not defined. So the linker issues an error because it can not find the variable definition.
You may declare a block scope variable with the extern specifier. But it will not be a variable definition. The declaration will refer to a variable with a linkage declared in a file scope.
For example consider the following demonstrative program
#include <stdio.h>
int x = 10;
void f( void )
{
extern int x;
printf( "x = %d\n", x );
}
int main(void)
{
f();
x = 20;
f();
return 0;
}
Its output is
x = 10
x = 20
That is there is defined the file scope variable x with the external linkage. And within the outer block scope of the function f the declaration of the variable x refers to the variable x in the file scope. It does not define a new object.