Global array question [modified]
-
I've declared an array like that in a header (the code should be a pure C code): int someMap[MAPSIZE_X][MAPSIZE_Y]; and I want to use it as a global variable. The problem is if I include that header in another file I get a linker error that this variable was already defined and I'm really stuck here and I have absolutely no clue what's going on and how I'm missing the point. If I use static it is fine but it isn't global any more. "extern int gameMap[MAPSIZE_X][MAPSIZE_Y];" doesn't work as I'm expecting. I get the linker error even if I don't use the array in any files.
modified on Thursday, April 7, 2011 6:34 AM
In the header file declare it as
extern int someMap[MAPSIZE_X][MAPSIZE_Y];
Give the declarationint someMap[MAPSIZE_X][MAPSIZE_Y];
in any one of the .cpp files.«_Superman_» _I love work. It gives me something to do between weekends.
-
In the header file declare it as
extern int someMap[MAPSIZE_X][MAPSIZE_Y];
Give the declarationint someMap[MAPSIZE_X][MAPSIZE_Y];
in any one of the .cpp files.«_Superman_» _I love work. It gives me something to do between weekends.
-
Just replace CPP in my reply with C.
«_Superman_» _I love work. It gives me something to do between weekends.
-
Just replace CPP in my reply with C.
«_Superman_» _I love work. It gives me something to do between weekends.
-
I've declared an array like that in a header (the code should be a pure C code): int someMap[MAPSIZE_X][MAPSIZE_Y]; and I want to use it as a global variable. The problem is if I include that header in another file I get a linker error that this variable was already defined and I'm really stuck here and I have absolutely no clue what's going on and how I'm missing the point. If I use static it is fine but it isn't global any more. "extern int gameMap[MAPSIZE_X][MAPSIZE_Y];" doesn't work as I'm expecting. I get the linker error even if I don't use the array in any files.
modified on Thursday, April 7, 2011 6:34 AM
int someMap[MAPSIZE_X][MAPSIZE_Y];
allocates memory for an array; if you include that statement in a header file, then include that header file in N different C files, you end up allocating N arrays, all with the same name, and the linker will complain as it can't have data blocks with global scope and conflicting names.extern int someMap[MAPSIZE_X][MAPSIZE_Y];
says: "there is an array somewhere, but this by itself does not allocate it"; so inserting that in the header file tells your C files they get access to the array, without allocating memory at all, and without creating linker problems. Of course you still need a singleint someMap[MAPSIZE_X][MAPSIZE_Y];
in one of the C files to actually allocate the memory; and that C file better also include the header file with theextern
statement. [ADDED] One elegant way of dealing with all this is described in Stefan63's message below. [/ADDED] :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
modified on Thursday, April 7, 2011 9:02 AM
-
I've declared an array like that in a header (the code should be a pure C code): int someMap[MAPSIZE_X][MAPSIZE_Y]; and I want to use it as a global variable. The problem is if I include that header in another file I get a linker error that this variable was already defined and I'm really stuck here and I have absolutely no clue what's going on and how I'm missing the point. If I use static it is fine but it isn't global any more. "extern int gameMap[MAPSIZE_X][MAPSIZE_Y];" doesn't work as I'm expecting. I get the linker error even if I don't use the array in any files.
modified on Thursday, April 7, 2011 6:34 AM
If you have plenty of such variables or declarations you can use a macro to automatically use the declaration in your header file as a definition exactly once:
// globals.h
#ifndef GLOBALS_H
#define GLOBALS_H#ifdef GLOBALS_C
define MYGLOBAL_API
#else
define MYGLOBAL_API extern
#endif
MYGLOBAL_API int someMap[MAPSIZE_X][MAPSIZE_Y];
#undef MYGLOBAL_API // clean up - we won't need that symbol outside this header
#endif// globals.c
#define GLOBALS_C // MYGLOBAL_API will be resolved to empty string
#include "globals.h" // defines the globals// every_other_soucre_file.c
#include "globals.h" // declares the globals, but doesn't define them
//...Using this technique, adding another global variable just requires adding it to globals.h, you never have to touch globals.c (or any other file) for that purpose! That said, it is always a good idea to keep the number of globals to a minimum, or, if possible, not use any at all. It's always very difficult to track an error that leaves a global in a bad state, because the problem may be caused anywhere in your program!
-
If you have plenty of such variables or declarations you can use a macro to automatically use the declaration in your header file as a definition exactly once:
// globals.h
#ifndef GLOBALS_H
#define GLOBALS_H#ifdef GLOBALS_C
define MYGLOBAL_API
#else
define MYGLOBAL_API extern
#endif
MYGLOBAL_API int someMap[MAPSIZE_X][MAPSIZE_Y];
#undef MYGLOBAL_API // clean up - we won't need that symbol outside this header
#endif// globals.c
#define GLOBALS_C // MYGLOBAL_API will be resolved to empty string
#include "globals.h" // defines the globals// every_other_soucre_file.c
#include "globals.h" // declares the globals, but doesn't define them
//...Using this technique, adding another global variable just requires adding it to globals.h, you never have to touch globals.c (or any other file) for that purpose! That said, it is always a good idea to keep the number of globals to a minimum, or, if possible, not use any at all. It's always very difficult to track an error that leaves a global in a bad state, because the problem may be caused anywhere in your program!
macros are wonderful when you know how to use them :)
-
int someMap[MAPSIZE_X][MAPSIZE_Y];
allocates memory for an array; if you include that statement in a header file, then include that header file in N different C files, you end up allocating N arrays, all with the same name, and the linker will complain as it can't have data blocks with global scope and conflicting names.extern int someMap[MAPSIZE_X][MAPSIZE_Y];
says: "there is an array somewhere, but this by itself does not allocate it"; so inserting that in the header file tells your C files they get access to the array, without allocating memory at all, and without creating linker problems. Of course you still need a singleint someMap[MAPSIZE_X][MAPSIZE_Y];
in one of the C files to actually allocate the memory; and that C file better also include the header file with theextern
statement. [ADDED] One elegant way of dealing with all this is described in Stefan63's message below. [/ADDED] :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
modified on Thursday, April 7, 2011 9:02 AM
-
If you have plenty of such variables or declarations you can use a macro to automatically use the declaration in your header file as a definition exactly once:
// globals.h
#ifndef GLOBALS_H
#define GLOBALS_H#ifdef GLOBALS_C
define MYGLOBAL_API
#else
define MYGLOBAL_API extern
#endif
MYGLOBAL_API int someMap[MAPSIZE_X][MAPSIZE_Y];
#undef MYGLOBAL_API // clean up - we won't need that symbol outside this header
#endif// globals.c
#define GLOBALS_C // MYGLOBAL_API will be resolved to empty string
#include "globals.h" // defines the globals// every_other_soucre_file.c
#include "globals.h" // declares the globals, but doesn't define them
//...Using this technique, adding another global variable just requires adding it to globals.h, you never have to touch globals.c (or any other file) for that purpose! That said, it is always a good idea to keep the number of globals to a minimum, or, if possible, not use any at all. It's always very difficult to track an error that leaves a global in a bad state, because the problem may be caused anywhere in your program!
-
you're welcome. In software development, getting things to work may be the goal, understanding how each part works is a necessary step to get things to work reliably. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.