0

I am learning how to use a extern variable, I wrote a simple program to try it but it doesnt seem to be working. I've looked at some examples but I don't know whats wrong.

Here is my code:

globals.h

#ifndef GLOBALS_H_
#define GLOBALS_H_

extern int gval;

#endif /* GLOBALS_H_ */

main.c

#include <stdio.h>
#include "globals.h"

int main() {
int gval = 4;
printf("1st value is: %i", gval);

printf("2nd value is: %i", modded());
}

modify.c

#include "globals.h"

int modded() {
return gval++;
}

The error seems to be that gval is undefined in modify.c, but I don't get how.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
tenkii
  • 449
  • 2
  • 10
  • 23
  • 2
    Here is a great related question describing how to use extern variables: http://stackoverflow.com/questions/1433204/how-do-i-share-a-variable-between-source-files-in-c-with-extern-but-how – Keith Aug 20 '14 at 01:41

5 Answers5

3

As it stands, you've declared a global variable gval in the header, and you've hidden that global declaration with a locally defined variable gval in the main() function. This is legal, but only sometimes (I'm tempted to say 'occasionally' or 'seldom') what is intended. If you use GCC, using the -Wshadow option would warn you about shadowing variables like that. It is generally a bad idea to shadow global variables.

The simplest fix to your code is to move the definition of gval outside main():

#include <stdio.h>
#include "globals.h"

int gval = 4;

int main(void)
{
    printf("1st value is: %i", gval);
    printf("2nd value is: %i", modded());
    return 0;
}

However, you should note that although it will compile and run, the second value printed will be the same as the first because modded() returns the unmodified version of the value. To see the effect, you need:

#include "globals.h"

int modded(void)
{
    return ++gval;
}

Were it my code, there'd be a declaration of modded() in globals.h. You should not be calling a function without a prototype in scope according to C99 and C11 (the old and current C standard). Of necessity, the original C89 standard was more lax about that rule; it had to be to accommodate the pre-existing non-standard code. However, for code written in the 21st Century, there's no real excuse for not having a prototype in scope before you use a function.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

A global extern variable must be defined somewhere, but in your code, the gval in main is a local variable, there's no definition of the global variable. This line

extern int gval;

is a declaration, not a definition. In other words, you must have

int gval;

somewhere outside all functions.

Even if a global gval were defined, note that the global gval is invisible in the scope of local gval

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
1

Change your main.c to

#include <stdio.h>
#include "globals.h"

int gval; // define (allocate space for) the global variable

int main(void) {
    // int gval = 4; -- wrong -- this defines and initializes a local variable that hides the global of the same name
    gval = 4; // use the global variable, assigning to it ... or you could initialize it at the definition above and omit this line
    printf("1st value is: %i", gval);

    printf("2nd value is: %i", modded());
}

and change modded to

int modded(void) {
    // return gval++; -- wrong -- this is postfix increment and returns the value *before* incrementing
    return ++gval; // use prefix increment
}

You also should have a modify.h that contains the prototype for modded that you include in main.c, or just put modded inside main.c before main.

Another approach is to change modded to not return a value, since it is changing a global, thus:

void modgval(void) {
    ++gval; // or gval++
}

And then in main:

    printf("1st value is: %i", gval);
    modgval();
    printf("2nd value is: %i", gval);
Jim Balter
  • 16,163
  • 3
  • 43
  • 66
0

This is a simple example describing how to share a variable between source files:

File 1:

  int GlobalVariable;         // explicit definition, this actually allocates as well as describing
  void SomeFunction(void);        // function prototype (declaration), assumes defined elsewhere, normally from include file.

  int main() {
    GlobalVariable = 1;
    SomeFunction();
    return 0;
  }

File 2:

  extern int GlobalVariable;  // implicit declaration, this only describes and assumes allocated elsewhere, normally from include

  void SomeFunction(void) {       // function header (definition)
    ++GlobalVariable;
  }

In this example, the variable GlobalVariable is defined in File 1. In order to utilize the same variable in File 2, it must be declared. Regardless of the number of files, a global variable is only defined once, however, it must be declared in any file outside of the one containing the definition.

In your case gval in main is a local variable, instead define a global variable and then use extern to share variable in different source files.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
PU.
  • 148
  • 9
0

Just put Gval before the main declaration and you're ready to go ;)