carlosn
carlosn

Reputation: 21

use a global variable in different files

So what i'm trying to do is using a variable from file1.c in file2.c. I've seen some answers already on here but I still get the same error as before. (error: variably modified at file scope)

What I have on file1.c is something like this:

extern int num = 0;
struct abc *do_something(int n){
    num = n;
}
/*more code below*/

now I wanted to use num on file2.c. I have this:

#include <something.h> /*which has file1.h inside*/
int num;
struct list_t list[num]; /*error here*/

/*code that uses the initialized list below*/

I tried using something like #define test_num num that it didn't work either. I need the list to be "global" on file2 so I can use it in different methods.

Upvotes: 0

Views: 87

Answers (3)

Clifford
Clifford

Reputation: 93566

The error in the list declaration is nothing to do with the definition of the global num, although that is also incorrect, but rather that you are attempting to dimension an array with with a variable outside of a function. Which is illegal and also nonsense. The value of num when list is instantiated is non-deterministic, and even if num were were initialised first, you'd be declaring an array of zero length.

You have the extern in the wrong place. In file1.c you should have:

int num = 0 ;

while in file2.c:

extern int num ;

Normally you would place the extern declaration in a header file - this allows the compiler to check the types match between declaration and definition, and allows the correct and consistent declaration to be used in multiple files with a single point of maintenance should you change the type for example.

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

extern int num ;  // Declaration

#endif

// file1.c
#include "file1.h"

int num = 0 ; // Definition/Instantiation

// file2.c
#include "file1.h"
int f()
{
    return num ;  // Use file1::num
}

All that said really don't use globals at all. It is bad practice and unnecessary. Rather:

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

  void setNum( int n ) ;
  int getNum() ;

#endif

// file1.c
#include "file1.h"

static int num = 0 ; // Protected by file scope
void setNum( int n ) { num = n ; }
int getNum() { return n ; }

// file2.c
#include "file1.h"

int f()
{
    setNum( getNum() + 1 ) ;  // Increment num (example r/w access)
    return getNum() ;
}

This has a number of advantages, including:

  • The set function can range check or validate
  • A variable may be made read-only by external functions (by omitting a setter)
  • A variable may be made write-only by external functions (by omitting a getter)
  • Nothing can take a reference to the variable and monkey with it in an uncontrolled manner.
  • In debug all accesses to the variable can be trapped by break-points in the access functions.

Further reading A Pox on Globals (related to embedded systems, but no less applicable generally.

Upvotes: 1

Henrik Carlqvist
Henrik Carlqvist

Reputation: 1168

To share a global variable between two files you should be aware that the variable belongs to the source file which has it declared without "extern". As such, it should also be initialized in that source file. Using extern tells your compiler it will find the variable from some other object file at link time.

As Joachim wrote you also have a problem with your array using this global variable.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409482

You have two problems actually. The first which relates to your error is that the value of num is unknown when the compiler sees the declaration of your array list. The compiler doesn't know anything from any other translation unit (a source file with all included header files), all it knows is the translation unit it's currently working on.

The second problem is more theoretical, and it's that the size of an array is fixed at the time of compilation, and changing the variable num at run-time will not change the size of the array.

The first problem can be solved by moving the initialization of num to the translation unit where it actually is used. Oh and not initialize it as zero, a zero-sized array is not of much use.

The second problem can be solved by using pointers and dynamic allocation using malloc and realloc.

Upvotes: 1

Related Questions