13

I have declared two global variables of same name in C. It should give error as we cannot declare same name variables in same storage class.

I have checked it in C++ — it gives a compile time error, but not in C. Why?

Following is the code:

int a;
int a = 25;
int main()
{

   return 0;
}

Check it out at : Code Written at Ideone

I think this probably is the reason

Declaration and Definition in C

But this is not the case in C++. I think in C++, whether the variable is declared at global scope or auto scope the declaration and definition is happening at the same time.

Could anyone throw some more light on it.

Now when I define the variable two times giving it value two times it gives me error (instead of one declaration and one definition).

Code at : Two definitions now

int a;
int a;
int a;
int a = 25;

int main()
{
return 0;
}
Community
  • 1
  • 1
ATul Singh
  • 490
  • 3
  • 15
  • @H2CO3 .. thanks for your suggestion but i was just trying to understand what was going on in it. But there are some situation where you can't even avoid the use the global variables. – ATul Singh Jun 30 '13 at 08:48

2 Answers2

13

In C, multiple global variables are "merged" into one. So you have indeed just one global variable, declared multiple times. This goes back to a time when extern wasn't needed (or possibly didn't exist - not quite sure) in C.

In other words, this is valid in C for historical reasons so that we can still compile code written before there was a ANSI standard for C.

Although, to allow the code to be used in C++, I would suggest avoiding it.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • I couldn't get the statement "Multiple Global Variables are "merged" into one. I have now defined the first one also,, and now its giving compile time error. – ATul Singh Jun 30 '13 at 08:24
  • 1
    In other words, all global variables with the same name will be converted to be one variable - so your `int a;` and `int a = 25;` will be referring to the same `int`-sized piece of memory. – Mats Petersson Jun 30 '13 at 08:24
  • Formally called *tentative definition* in C. You can tentatively define an object as many times as you want in a single translation unit and they'll be "merged" and resulting type is the composite of all tentative definitions. In your case, it's just `int`. – P.P Jun 30 '13 at 08:26
  • @KingsIndian But when i tentatively **define** two variable in global scope with same name it gives me error :: I am assuming ` int a; //to be declaration at global scope and int a = 12 ; //to be definition at global scope.. ` – ATul Singh Jun 30 '13 at 08:32
  • Well, obviously, if you give it a value, the compiler has to generate something to define that variables values. If you do that twice, it will be an error, because you would end up with two distinct variables with one name - which one do you want to use? You are only allowed to give it a value once. – Mats Petersson Jun 30 '13 at 08:36
  • 1
    C does not “merge” multiple global variables into one. A declaration or tentative definition (that is not resolved to a definition) does not define a global variable. The code in the question contains only one definition of a global variable, so there is nothing to merge. In this case, the tentative definition remains only a declaration, not a definition. For example, `int a = 25; int a = 25;` would produce an error, not a merging of the two `a` objects. – Eric Postpischil Jun 30 '13 at 12:34
  • Right, an uninitialized variable is put into a "common" section, which is then merged by name by the linker (if there isn't a data section element by the same name) I did simplify the statement a bit to make it easier to understand. – Mats Petersson Jun 30 '13 at 17:35
2

This is what the classic text "The C Programming Language" by Dennis Ritchie and Brain Kernighan says:

  1. An external declaration for an object is a definition if it has an initializer.

  2. An external object declaration that does not have an initializer, and does not contain the extern specifier, is a tentative definition.

  3. If a definition for an object appears in a translation unit, any tentative definitions are treated merely as redundant declarations.

  4. If no definition for the object appears in the translation unit, all its tentative definitions become a single definition with initializer 0.

So for example:


extern int a =123; // this declaration is a definition as a is initialized to 123

int a; //this is a tentative definition

int a;
int a;
int a;
/*all the above the three tentative declarations are redundant*/

int a;
int a;
int a;

Futher in the code if no where do something as a=100 where we consider a corresponding to this global scope variable and not any other local variable with the same name and type, then ultimately, the global variable a shall be initialized to 0


Abhishek Ghosh
  • 597
  • 7
  • 18