Ok, I try to explain with my poor english
both a in a.c and b.c point to same location and have global scope, a
in b.c is redeclared, all variables declared without static duration
outside a function have global scope
That's not really the problem. Â The program is undefined because it has
two external definitions of an object with the same name.
Unfortunately your terms are rather confused. Â Normally this does not
matter, but in this case using the right terms helps to get everything
clear.
In C, a named object is characterised by three properties: the scope of
the name, the lifetime of the object and the linkage of the name. Â These
are related but also to some extent independent.
An external definition of an object (one that sits outside of any
function) gives it static duration -- even if it does not use the word
static! Â If an external declaration does use the keyword "static", this
alters the linkage but not the lifetime.
C does not have global variables in the same sense that some other
languages do. Â Normally, when people talk about "glabals" in C they mean
objects with external linkage, static duration and file scope. Â Using the
term "global" (or "global scope") is rarely a problem, but in this case
it lies at the heart of the OP's confusion so I think it pays to use the
right language. Â Here are some examples:
----------------
int a = 3; /* The name has file scope and external linkage.
       The object named has static duration */
static int b = 42; /* The name has file scope but internal linkage.
           The object has static duration */
void f(int a) /* f has file scope and external linkage but functions
         don't have any storage duration.
         a has block scope, no linkage and automatic duration. */
{
  int b; /* block scope, no linkage, automatic duration. */
  static int c; /* block scope, internal linkage and static duration */
  extern int d; /* block scope, external linkage and static duration */
}
void g(int x); /* x has function prototype scope, no linkage and
         (insofar as it makes any sense) automatic duration. */
int t; /* A tentative definition of a name with file scope and external
     linkage naming an object with static duration. *.
int t2; /* Another tentative definition. */
int t2 = 42; /* Not a re-definition since the previous one was
        tentative. */
/* Here, at the end of the translation unit, the tentative definition of
  't' is treated as if it had been "int t = 0;".  I.e. the tentative
  definition becomes a real one. */
----------------
There are two rather curious details. Â An object with automatic duration
that is not a variably modified array exists from entry into the block
until the block is exited[1]. Â A variably modified array only exists
from the point of it's definition:
 int peculiar(unsigned int s)
 {
    int *ip = 0;
 top: if (ip) return *ip;
    int a[1];
    a[0] = 42;
    ip = a;
    goto top;
 }
is well-defined but if 'a' were changed to be "int a
;" then the
behaviour would be undefined.
[1] Even this needs care to define properly but I'll leave it as
self-evident for the moment.