7

I have the below C code and I am expecting it to throw an error like "multiple declaration of variable", but it is not doing so.

#include <stdio.h>

int i;        
int i;    

int main()
{
    printf("%d",i);
    return 0;
}

Now the output is 0, but why?

And one more thing below code gives error what is expected

#include <stdio.h>


int main()
{
    int i;        
    int i;    

    printf("%d",i);
    return 0;
}

O/p is error saying re declaration of i

Bart
  • 19,692
  • 7
  • 68
  • 77
Amit Singh Tomar
  • 8,380
  • 27
  • 120
  • 199
  • i am using online compiler to run this code. – Amit Singh Tomar Jul 21 '11 at 10:45
  • 1
    After the edit: in the 2nd snippet, the definitions of `i` occur inside a function (they don't occur at file scope) and are not tentative definitions. – pmg Jul 21 '11 at 11:01
  • Why is not tentative definition when occurs inside block because its just declaration not defination?? – Amit Singh Tomar Jul 21 '11 at 11:03
  • @Amit: a declaration of an object at block scope can be achieved with the `external` keyword: `external int i;`, but it is better to specify such declarations at file scope anyway. – pmg Jul 21 '11 at 11:16

1 Answers1

18

The first definition of i is a tentative definition (the 2nd is also a tentative definition). They are "de facto" definitions though (and definitions serve also as declarations), no mistake about it.

Quote from the Standard:

6.9.2/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.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • Thanks @pmg for your response but can you please put this whole thing in simple way.i mean i can have as many declarations as i want?? – Amit Singh Tomar Jul 21 '11 at 10:53
  • No initializers. No override that says its elsewhere. No conflict. Standard says "in that case, declare here and initialize to zero". – Donal Fellows Jul 21 '11 at 10:55
  • 1
    @Amit: basically, definitions without an initializer (`int i;`) are tentative definitions. C allows multiple tentative definitions of an identifier. Definitions with an initializer (`int i = 0;`) are not tentative definitions and cannot be used more than once. – pmg Jul 21 '11 at 10:58
  • 1
    Non-tentative definitions are called *external definitions* - you can have many tentative definitions of the same identifier, but only one external definition. – M.M Feb 27 '17 at 20:45