daniel
daniel

Reputation: 587

Understanding how extern works

The way I understand extern is that we are able to declare a variable anywhere in a program and use it, but we can just define it once. I am getting an error in the following program.

hello.c

#include <stdio.h> 
#include "function.h"
extern int c;
int main() 
{ 
    int c;


    c=10;
    printf("%d\n",c);
    printExternValue();

    return 0;

}

function .h

void printExternValue();

function .c

#include "function.h"
#include "stdio.h"
extern int c;
void printExternValue()
{
    printf("%d\n",c);
}

I expect this program to print out:

10
10

But it's not doing so since it's giving an error. I re-declared the variable c in the function.c file with the intention of using the value that is stored in the so called external storage.

Error: function.c:(.text+0x6): undefined reference to `c'

I am currently reading a PDF file from tutorialspoints which I think to be very redundant since the intention of creating a variable with the aggregate extern is useless. The right way this should be done is that they define the variables outside the function is that right?

#include <stdio.h> 

// Variable declaration: 
extern int a, b; 
extern int c; 
extern float f; 

int main () 
{ 
  /* variable definition: */ 
  int a, b; 
  int c; 
  float f; 

  /* actual initialization */ 
  a = 10; 
  b = 20; 

  c = a + b; 
  printf("value of c : %d \n", c); 

  f = 70.0/3.0; 
  printf("value of f : %f \n", f); 

  return 0; 
} 

Upvotes: 2

Views: 216

Answers (2)

ChuckCottrill
ChuckCottrill

Reputation: 4444

Define your variable once in one of your files (to reserve space),

int c = 0;

Declare your variable references everywhere else (in all of your other files) (to reference said space),

extern int c;

But that could be confusing, so name them indicative of the 'global' use,

int glob_a, glob_b;
int glob_c;
float glob_f;

And declare your variable references everywhere else,

extern int glob_a, glob_b;
extern int glob_c;
extern float glob_f;

But you really want to avoid littering you namespace, so when you have a collection of globals, declare a struct that contains them (in a header file probably called globals.h),

typedef struct globals_struct {
    int a, b;
    int c;
    float f;
} globals_t;

And once (in your file main.c that declares main()), you define the struct,

#include globals.h
globals_t globs;

And everywhere else, reference the space,

#include globals.h
extern globals_t globs;

Often, you will see a stanza such as this, where MAIN is only declared in one file,

#ifndef MAIN
extern globals_t globs;
#else
globals_t globs;
#endif

Use your globals,

int my_a = globs.a;
int my_b = globs.b;
int my_f = globs.f;

Notice how you have avoided needless namespace pollution?

Because extern just tells the compiler (actually the linker) that a variable is being defined elsewhere and needs to be linked against.

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320481

Variable declread as

extern int c;

is an external declaration that potentially requires an external definiton. "External" in this case means "located outside of any function". Your c declared locally in main() does not fullfill that role.

Since you are using that externally declared variable c in your code you have to define it and define it only once.

You need

int c;

or

int c = 0;

or

extern int c = 0;

it one of your implementation files, at file scope. All of these are definitions. Any of them will define your variable.

Upvotes: 1

Related Questions