0

Hi I have following 2 files in a.c I have

#include <stdio.h>

int i;
static int j;
int main()
{
        printf("i = %d\n",i);
        printf("j = %d\n",j);
        return 0;
}

and in b.c I have

#include <stdio.h>

extern int i=2;
extern int j=5;

In this example when I run, I get answer as 2,0 but complier throws warning initialized and declared ‘extern’ for both variables.

How b.c is able to access j and not throws error since scope of j is for a.c only?

arya
  • 81
  • 1
  • 8
  • Please see [other answers](http://stackoverflow.com/questions/4268589/warning-in-extern-declaration) to this question. The warning itself has nothing to do with `a.c`. Even if you compile `b.c` on its own you would get the same warning. – kaylum Sep 30 '15 at 11:26
  • Why do you say "scope of j is for a.c only"? It's declared `extern` in `b.c`. – David Schwartz Sep 30 '15 at 11:29
  • As `j` is declared static in `a.c` I think scope is limited to that file only. – arya Sep 30 '15 at 11:31
  • @arya Yes it is. That is why your main prints `0` for `j` and not `5`. It is not clear what you are really asking. – kaylum Sep 30 '15 at 11:33
  • Ok let me put like this, When I declare `static int j=0` in `b.c` and I make it `extern ` in `a.c` & print value of `j` in `main` function of `a.c` then I get linker error as `undefined reference to `j'`. Then vice a versa should also do the same.right? – arya Sep 30 '15 at 11:36
  • You are right, because of static keyword. – LPs Sep 30 '15 at 11:38
  • @arya You are confusing declarations and definitions. The code as shown in your question has **two** definitions of `j`. They are at different scopes and do not clash. The example in your above comment is not complete. `extern` is not meaningful if you initialise the global. If you don't initialise it then yes you will get an undefined error in the comments example. – kaylum Sep 30 '15 at 11:43
  • Conversely, the code shown has only **one** definition of `i`. They are both at the same (global) scope. Since one is uninitialised the compiler treats them as the same variable. If you tried to initialise `i` in `a.c` you will get a multiply defined variable compiler error. – kaylum Sep 30 '15 at 11:47

3 Answers3

1

First of all, initializing a variable at the same time as you declare it as extern doesn't make any sense. Which is why you get a compiler warning. C allows it if the variable is at file scope, but as always, C allows many bad things.

Also note that the use of extern is almost always bad practice and should be avoided.

Now for the code, i behaves as expected because the i in both files refer to the same variable. j on the other hand is static, so the scope of that variable is reduced to the local file. There is a rule in the standard saying that all static variables must be initialized to 0 unless the programmer initialized them explicitly. So the value of j will be 0.

Since j is static, extern int j; refers to "another j somewhere else", because there is no j variable visible to the file where you wrote the extern. Since "another j somewhere else" isn't used by the program, that variable will simply get discarded.

static and extern are in many ways each other's opposites. If you think it makes sense to declare the same variable both static and extern, you need to study the static keyword more.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

a.c

#include <stdio.h>
int i;
static int j;
extern void display();
int main()
{
        printf("i = %d\n",i);
        printf("j = %d\n",j);
        display();
        return 0;
}

b.c

#include <stdio.h>
extern int i;
extern int j;

void display()
{
     printf ("%d",j);
}

c.c

#include <stdio.h>
extern int i=2;
extern int j=5;
void display()
{
   printf ("%d",j);
}

If you compile a.c and b.c GCC will complain

undefined reference to `j'.

Because the program trying to access j which is not defined in the scope of b.c

If you compiple a.c and c.c GCC will throw warning as you stated

warning: âjâ initialized and declared âexternâ

and presumes j defined in c.c and will not throw any errors.

In your case if you remove assignments in b.c you will not found any error at the time of compilation because in b.c there is no function which is accessing value of j.

Gangadhar
  • 10,248
  • 3
  • 31
  • 50
0

static data is by default initialized with 0 if not told otherwise, this is why you get 0 as answer, it has nothing to do with b.c module. Also a variable can't be declared both static and extern, sounds like a contradiction to me.

When using extern you should only declare a variable(no space is set to hold it in memory), definition for that variable will be in other module. In a simple way extern tells to the compiler, hey don't worry about this variable its defined elsewhere in a module, so don't set any space for it.

Why your compiler doesn't throw an error? Is b.c linked in your program with a.c? Try to do this and see what happens.