Search code examples
clinker-errorsexternalstatic-linking

How can a static variable from other file accessed here on the C program below?


#include <stdio.h>
#include <stdlib.h>
int function(int);

int main()
{
    int a=1;
    extern b;//can be only declared
    printf("a=%d\n",function(a));
    printf("b=%d\n",value());
    return 0;
}
int function(int v)
{
    return v+1;
}

In file1.c :

static int b=20;

int value() //can't be used on a static function
{
    return b;
}

In the code above though I've made variable b as static, it's accessible from other files. How can it be accessed, as the static keyword shouldn't allow the variable to be accessed from other files right? I'm bit confused.


Solution

  • This statement

    static int b=20;
    

    means the variable b will only be visible in its translation unit i.e. in file1.c, in which you have defined it.

    In the main(), which is supposed to be in a different file, you have only declared b but not used it. Try to use it and you will find that linker will fail because it will not find the definition of b.

    int main()
    {
        int a=1;
        extern int b;    // note the type int in declaration. You have missed it.
        printf("access b = %d\n", b);   // <==== this won't work
        return 0;
    }
    

    Try to compile your program with above changes and you will see that the linker will throw error.

    With above mentioned changes in main(), just remove the static keyword from variable b definition in file1.c file and above program will link successfully because then b will be a global variable which has external linkage.

    From the value() you are returning the value that variable b hold which has nothing to do with whether b is static or non-static.

    The lifetime of a static variable is the entire run of the program. You can access the static variable outside of it's scope/translation unit if you have the address of that static variable. Check this:

    File file1.c :

    #include <stdio.h>
    
    static int b = 20;
    
    int * retaddr_b (void) {
        return &b;
    }
    
    void print_b (void) {
        printf ("b = %d\n", b);
    }
     
    

    File main.c:

    int * retaddr_b (void);
    void print_b (void);
    
    int main(void)
    {
        print_b();                 // print static variable b value 
        int * ptr_b = retaddr_b(); // ptr_b pointing to b
        *ptr_b = 99;               // dereference ptr_b and assign different value
        print_b();                 // print static variable b value
        return 0;
    }
    

    Output:

    b = 20
    b = 99