The second one is not a definition. It's a declaration.
From the ISO C standard draft N1570, Section 6.9.2:
1 If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.
2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static
, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.
So when you write
int x;
in file scope, it's not necessarily a definition. It's a declaration, which is fine to be repeated.
This is called tentative definition in C. See more here, here and here.