12

I have tried the following code:

File1.c:

int x;

File2.c:

extern char x;
main()
{
    x=10;
    ....
    ....
}

and compiled as

$gcc File1.c File2.c

and I didn't get any error but I was expecting one.

mhu
  • 17,720
  • 10
  • 62
  • 93
Adi
  • 729
  • 2
  • 6
  • 13

1 Answers1

18

In File.c, you promise to the compiler that x is of type char. Since every translation unit is compiled separately, the compiler has no way of verifying this, and takes your word for it. And the linker doesn't do any type checking. You end up with an invalid program that builds with no errors.

This is why you should use header files. If File1.c and File2.c both got an extern declaration of x from the same header, then you would get an error when compiling File1.c (because the definition doesn't match the declaration). [Hat tip @SteveJessop]

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • That's it. And, since 10 is both a valid `int` and a valid `char`, compilation works fine. – Fabien Mar 22 '13 at 09:15
  • Thanks Steve for clarifying that to me..But i got curious and now i initialized the global variable x as char in file1 and declared it as int in file2 and i have put a value of 1000 which char cant handle and to print it..By your explanation now i am expecting an run time error and i did not get one.. – Adi Mar 22 '13 at 11:07
  • 1
    @BillHicks: The behaviour of your code is undefined (http://en.wikipedia.org/wiki/Undefined_behavior). It does not have to crash or give you a runtime error. It is free to malfunction (or not) in other ways. – NPE Mar 22 '13 at 11:11
  • @Fabien: No, compilation works fine because the compiler doesn't know that you are going link the result of compiling File2.c against the rsult of compiling File1.c that defined x as an int. – Axel Mar 22 '13 at 12:59
  • 1
    @Axel yes, but if, in File2.c, it was defined as, say, an ` extern char*`, the compiler would have complained for that reason. – Fabien Mar 22 '13 at 13:21