2

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; 
} 
daniel
  • 557
  • 1
  • 4
  • 15
  • You're getting a link-time error about 'undefined symbol `c`'? You should quote the error message exactly, for the code you show. The `c` defined and referenced inside `main()` is nothing to do with the `extern int c;` declared outside `main()`. – Jonathan Leffler Apr 04 '17 at 00:11
  • Yes sorry, I updated the thread. – daniel Apr 04 '17 at 00:12
  • 3
    Since your code never defines `c`, it isn't surprising that it isn't found. You need an `int c;` or `int c = 314159265;` or something similar outside a function in one of the files you link to create your program. – Jonathan Leffler Apr 04 '17 at 00:13
  • Ok, so I defined int c in the main, but it's out of scope for any function defined in other file. Is that correct? – daniel Apr 04 '17 at 00:14
  • No, you didn't (define `int c` in the main file). The `int c;` inside `main()` is a local (automatic) variable that hides (shadows) the one declared outside `main()` with `extern int c;`. The two share the same name, but are otherwise 100% unrelated. And yes, the `c` defined inside `main()` can only be accessed by _name_ from inside `main()`; it's a local variable, valid only in the function. – Jonathan Leffler Apr 04 '17 at 00:16
  • OHHH ok, so adding the extern int c inside the main function will do the job. – daniel Apr 04 '17 at 00:16
  • 1
    No, you still need to define `c` outside of a function. – aschepler Apr 04 '17 at 00:19
  • No; 'adding the `extern int c` inside the main file' will not do the job. You need an un-externed `int c;` or `int c = 3;` (for any chosen initializer) in either the file containing `main()` (but outside the `main()` function, or any other function), or you need a similar definition in some other file (presumably `function.c`), again with the definition outside any function in the file. Your header should be responsible for declaring the variable: `extern int c;` belongs in the header (and you should not write it in your source files). One of your source files is responsible for defining it. – Jonathan Leffler Apr 04 '17 at 00:19
  • See also [How to use `extern` to share variables between source files](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files-in-c/1433387#1433387). Stop no later than the second invitation to read no further — the remaining material would confuse you at this stage. – Jonathan Leffler Apr 04 '17 at 00:21
  • 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 how this should be done is to define the variables outside the function. is that right?. Check my updated thread. – daniel Apr 04 '17 at 01:01
  • By the way, I read your post though. That's why I am asking this question. – daniel Apr 04 '17 at 01:10

2 Answers2

1

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

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.

ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42