C says this behavior is undefined.
(C99, 6.9p5) "If an identifier declared with an external link is used in the expression (except as part of the operand of the sizeof operator, the result of which is an integer constant), somewhere in the entire program there must be exactly one external definition for the identifier, in otherwise there should be no more than one "
Being undefined behavior means that the linker can interrupt the binding process in the presence of multiple definitions of external objects.
Linkers are now good (or evil, you can choose) and usually have default extensions to handle multiple definitions of external objects and in some cases don't crash.
If you use gcc and ld from binutils, you will get an error if your two objects are explicitly initialized. For example, you have int x = 0; in the first translation unit and double x = 0.0; .
Otherwise, if one of the external objects is not explicitly initialized (the situation in your example), gcc will seamlessly combine the two objects into one symbol. You can still ask the linker to report a warning by passing it the --warn-common option.
For example, when linking modules:
gcc -Wl,--warn-common module1.o module2.o
To interrupt the binding process, you can ask the linker to treat all warnings as errors using the --fatal-warnings ( -Wl,--fatal-warnings,--warn-common ) option.
Another way for the bind process to be aborted is to use the -fno-common option of the compiler, as explained by @teppic in his answer. -fno-common prevents external objects from receiving a common character type when compiling. If you do this both for the module and then for the link, you will also get a linker error of several definitions.
gcc -Wall -fno-common -c module1.c module2.c
gcc module1.o module2.o