Does C have One Definition Rule like C++?

I think what you’re looking for is chapter §6.2.7 from the C11 standard, Compatible type and composite type, (emphasis mine)

All declarations that refer to the same object or function shall have compatible type;
otherwise, the behavior is undefined.

and related to compatible type,

Two types have compatible type if their types are the same.

In your case, int and unsigned int are not compatible types. Hence undefined behavior.

Just to add a bit of clarity, in your source 2, unsigned int var_global; is a declaration, and it does not match the other declatation (and definition), so, this is UB.

That said, a statement like

 printf("%d \n",var_global);

will always consider the argument to %d to be of type int. In case the type and the format specifier does not match, you’ll again invoke undefined behavior.


EDIT:

After the edit, the answer is, use -fno-common to get the desired error. (missing extern is what you’re bothered with, I believe).

Quoting from online GCC manual,

-fno-common

In C code, controls the placement of uninitialized global variables. Unix C compilers have traditionally permitted multiple definitions of such variables in different compilation units by placing the variables in a common block. This is the behavior specified by -fcommon, and is the default for GCC on most targets. On the other hand, this behavior is not required by ISO C, and on some targets may carry a speed or code size penalty on variable references. The -fno-common option specifies that the compiler should place uninitialized global variables in the data section of the object file, rather than generating them as common blocks. This has the effect that if the same variable is declared (without extern) in two different compilations, you get a multiple-definition error when you link them. In this case, you must compile with -fcommon instead. Compiling with -fno-common is useful on targets for which it provides better performance, or if you wish to verify that the program will work on other systems that always treat uninitialized variable declarations this way.


I don’t know of any mention of the wordings “one definition rule” in the C standard, but along the line, you can look into annex §J.5.11, Multiple external definitions,

There may be more than one external definition for the identifier of an object, with or
without the explicit use of the keyword extern; if the definitions disagree, or more than
one is initialized, the behavior is undefined.

Leave a Comment