0

Sorry this is a basic question, but all my research just barely missed answering my question and I just wanted to double check before I write all my code with an assumption. I'm using C and I have a header file with some variables declared (ints, char arrays, int arrays). If I have a function that makes use of these global variables I am assuming that I can use the variables without passing them?

EXAMPLE HEADER FILE:

int state;
int lnArray[];

C FILE:

void function(){ 
    int i;
    for(i=0;i<5;i++;){
        if(lnArray[i]<10)    
        state = lnArray[i];
    }
}
torrential coding
  • 1,755
  • 2
  • 24
  • 34
Sams
  • 197
  • 1
  • 3
  • 14

5 Answers5

6

Note that your header file as written defines the global variable state (it declares an incomplete array lnArray); it should just declare them:

extern int state;
extern int lnArray[];

Then, in one of the source files (a source file which also includes the header), you write:

int state = 0;
int lnArray[XXX];   //  XXX is an enum or #define that gives the array size

Or you can have an initializer for lnArray that gives the array size.

You might just get away with what you've got if your compiler uses the 'common definition' mechanism; many do. But add an initializer and you're hosed.

See also: What are extern variables in C?

Note that global variables are generally not a good idea; it is difficult to track which code is accessing them and modifying them. People go to great lengths to avoid global variables. Global constants are a different matter; they present fewer problems, though you still don't use them willy-nilly.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
3

That's correct. It's why they're called "global" variables: they're available in any scope.

Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • Okay. Thank you. I just wanted to be sure before I needed to rewrite the code or had a ton of errors. – Sams Apr 03 '12 at 03:46
  • 2
    Now that you know what they are, use them judiciously. Don't use them just to avoid passing parameters. Use them when it makes sense to have global data (i.e. need one instance of something and referenced in a lot of places). There are *many* downside risks to global data. Tread with care. – Amardeep AC9MF Apr 03 '12 at 03:56
  • 2
    However, you not only *declared* the variables in your header, you also *defined* them. You shouldn't do that: in case, several modules use the same hader you will get name conflicts. – Matthias Apr 03 '12 at 03:57
  • In the real function if I passed everything it would be 2 ints, 1 int array, 1 char array, and 1 pointer array. I was trying to cut down on at least some of the parameters. – Sams Apr 03 '12 at 04:03
2

The example that you've given is correct, but is prone to "redeclaration" linker errors.

The preferred way of using global variables is:


/* example.h */
extern int state;
extern int lnArray[];

/* example.c */
int state;
int lnArray[SOME_SIZE_HERE];

By declaring the externs in the header file you're able to #include <example.h> as many time as you like, from as many different source files as you like without state or lnArray being redeclared.

Andrew Edgecombe
  • 39,594
  • 3
  • 35
  • 61
1

yes, but be a bit careful if you are planning to include it in some other header.

http://tread.wordpress.com/2007/06/18/declaring-global-variables-in-header-files/

Are global variables bad?

Community
  • 1
  • 1
chikuba
  • 4,229
  • 6
  • 43
  • 75
1

You need to be careful here. "Global" variables are those that are available to any point in the code but there's no formal definition of global in the standard - it uses more formal terms like scope, storage duration and linkage.

One definition of global applies to a single file, another can apply across multiple files.

With you particular setup, if you include that header file in multiple C source files, then try and link them together, you'll get link errors because each object file has their own copy of the variables, and they're all trying to export them.

If you want your variables to be global for a single source file, put them at the top of that source file and make them static (effectively invisible to the linker):

static int state;

This means every function in that file can get at them yet they don't interfere with other files.

However, if you want your variables to be global across all source files, put the declaration in a header file and the definition in one C source file. A declaration declares that something exists while a definition brings it into existence:

something.h:
    extern int state;                     // declare it

file1.c:
    #include "something.h"                // declare it (in header)
    int state;                            // AND define it.
    // Now you can use state anywhere.

file2.c:
    #include "something.h"                // declare it (in header)
    // Now you can use state anywhere.

This means there is one copy of state that all files have access to.


In terms of using global variables, it should generally be avoided as much as possible. Using them makes encapsulation much more difficult and exposes the innards of your code to manipulation from outside.

The basic rule is to Use the smallest possible scope for any individual item, that still allows you to achieve your ends. And sometimes, that means passing things around.

If you really don't want to pass them around, at least isolate all the data, and code that manipulates it, to a single file so you can hide it that way.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953