I have an ILE C projet on the as400 which, when being linked, gives me either an error of multiple redefinition of global variables or undefined references if I put the global variable extern.
Here is the code in its simplest form:
main:
#include "Header1"
int main(int argc, char** argv){
int x = Foo();
return 0;
}
Header1
#ifndef HEADER1
#define HEADER1
struct MyStruct{
int x;
};
struct MyStruct g_myStruct; /* My global struct variable. */
int Foo(void);
#endif
Header1 implementation
#include "Header1"
#include "Header2"
int Foo(void){
g_myStruct.x = 432;
return Bar();
}
Header2
#ifndef HEADER2
#define HEADER2
int Bar(void);
#endif
Header2 implementation
#include "Header2"
#include "Header1"
int Bar(void){
return g_myStruct.x;
}
Each file compiles fine. Only when I try to link them I get the following error:
Multiple strong definitions . . . . . . . . . : 2
Symbol Type Library Object Bound Identifier
*MODULE MYLIB 1 *YES g_myStruct
*MODULE MYLIB I2 *YES g_myStruct
With the extern keyword in front of my global struct declaration, I get this error:
Unresolved references . . . . . . . . . . . . : 2
Symbol Type Library Object Bound Identifier
*MODULE MYLIB I1 *YES g_myStruct
*MODULE MYLIB I2 *YES g_myStruct
You're including file header1.h in several different source files.
This leads to several different instances of g_myStruct, thus multiple redefinition.
Declare this variable extern in file header1.h, and instantiate it in one of the source files.
For example:
File header1.h:
extern struct MyStruct g_myStruct; /* My global struct variable. */
File header1.c:
struct MyStruct g_myStruct; /* My global struct variable. */
Global variables work pretty much like global functions.
In the header file, you put a declaration. For functions, this looks like:
int Foo(void); // or 'extern int Foo(void);'
For variables, you need extern (this is optional for functions):
extern struct MyStruct g_myStruct;
Then, in the implementation file, you put the definitions:
#include "Header1"
struct MyStruct g_myStruct;
int Foo(void){
...
}
Related
I want to declare and define (with a default value) a variable in a .h file.
When I do that I get
/tmp/cc19EVVe.o:(.data+0x0): multiple definition of `car_name'
/tmp/cc3twlar.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
How do I achieve my goal? Namely, to declare and define with default values a variable in a .h file and use that variable in multiple .c files?
Here is the A.h file
char * car_name = "Volkswagen";
void execute();
Here are the first file that uses the variable car_name defined in A.h: (The file is called execute.c)
#include "A.h"
#include <stdio.h>
#include <string.h>
void execute(){
int len = sizeof(car_name) + 2;
char car_name_with_new_line[len];
strncat(car_name_with_new_line, car_name, sizeof(car_name));
strncat(car_name_with_new_line, "\n", 1);
printf(car_name_with_new_line);
}
That's the other .c file: (It's called main.c)
#include "A.h"
int main(int argc, char ** argv){
execute();
return 0;
}
The answer is simple: Define your variables in exactly one compilation unit (.c file). Declare them in the header file associated with that .c file.
foo.h
extern char *g_name; // Declare that g_name exists
foo.c
#include "foo.h"
char *g_name; // Define g_name in one place
static char *m_private; // Private to foo.c, not "exported" via foo.h
main.c
#include "foo.h"
void somefunc(void)
{
// use g_name
}
1) define the variable in a single file, do not add a static modifier
2) place an extern statement for that variable in the header file.
then only one instance of the variable exists anyone that includes the header file can access the variable.
Note: it is poor programming practice to have global variables.
Good programming practice is to write accessor functions and hide the variable within a file. similar to the following:
static int myVariable = 0;
void setMyVariable( int myVariableParm )
{
myVariable = myVariableParm;
}
int getMyVariable( void )
{
return myVariable;
}
I need to pass an array of structures defined in a file "file1.c" to a function, lets say "myFunc()", defined in another file "file2.c". The thing is that I don't know how to set the prototype of myFunc() in my header file "header.h" or in the function itself in my file2.c because the struct will only be defined in file1.c . Here is an example.
file1.c
#include "header.h"
#define dim 30
#define searchAgents 30
struct Wolf{
double pos[dim];
double fitness;
}Pack[searchAgents];
int main(){
myFunc(Pack); //not sure it's ok
return 0;
}
file2.c
#include "header.h"
void myFunc(struct Wolf Pack[]){ //I don't know how to set this argument
Pack[0].pos[0] = 1; //just an example
}
header.h
#ifndef HEADER_H_
#define HEADER_H_
void myFunc(struct Wolf); //I don't know how to set this prototype
#endif
I read about passing structures to functions but it's different when you have your function defined in another file. Thanks for your time.
header.h
#ifndef HEADER_H_
#define HEADER_H_
//Add all needed includes
#define dim 30
#define searchAgents 30
typedef struct Wolf{
double pos[dim];
double fitness;
}Pack; //Declaration
void myFunc(Pack *);
#endif
In main
#include "header.h"
int main(){
Pack packArray[searchAgents]; //Definition or initialization if you like
myFunc(packArray);
return 0;
}
file2.c
#include "header.h"
void myFunc(Pack *pack){ //just a pointer to Pack structure
pack[0].pos[0] = 1;
}
You can try making Pack[] as an extern type variable
extern keyword tells the compiler that the variable is define in some other .c file which is compiled along with this file with -o option in gcc compiler .
ex
extern Pack[10];
Say I have 3 files: file1.c, file2.c and globals.h. file1.c and file2.c both include globals.h. file1.c contains a struct that file2.c needs to use. Is it better to make the struct itself extern or create a pointer to the struct and make that pointer extern in globals.h?
If I understand correctly and your "a struct" is supposed to be a global object (which is a questionable design choice), then I'd do it like this:
foo.h:
typedef struct foo_struct
{
/* ... */
} foo;
extern foo the_foo;
foo.c: [If you like and if it makes sense, you can merge this into file1.c.]
#include "foo.h"
foo the_foo = { /* ... */ };
file1.c and file2.c:
#include "foo.h"
#include "global.h"
/* ... */
I have 4 Files = pic.h, main.c, framehandle.c and framehandle.h
Both pic.h and framehandle.h are included within my main:
#include "pic.h"
#include "framehandling.h"
pic.h has the following struct definition.
struct f
{
unsigned sleep : 1;
unsigned push : 1;
unsigned rx : 1;
unsigned tx : 1;
unsigned validPacket : 1;
};
I declare this struct in my main.c file using
struct f flag;
when I try to use this inside framehandle.c I get an undeclared error which I understand.
To solve this I add the following inside framehandle.h:
extern struct f flag;
However the compiler is still complaining that flags are not declared inside framehandle.c
What am i doing wrong?
wouldn't extern struct f flag; supposed to tell the compiler to look else where for the decleration?
wouldnt't placing this inside the subjects header be the correct place?
--Edit--
I am adding the sequence of my include files and my variable declerations
#include "pic.h"
#include "framehandling.h"
struct f flag;
void main(void)
{ }
It will depend on if you have declared struct f flag; in main.c as global or local. If you have it declared inside of the function, you will have to move the declaration outside the function.
The solution to the problem was that extern struct f flag should have been inside pic.h. It makes sense in a way, to place it right after the decleration.. I would also like to thank you all for your input.
If the syntax of extern is
extern <type> <name>;
how do I extern if I have an unnamed, single use struct:
struct {
char **plymouthThemes;
char *plymouthTheme;
} global;
I've tried
extern global;
without any type, and it doesn't work.
Or, do I have to name the struct?
You need to name your struct and put it in a .h file or included the definition by hand in every source file that uses global. Like this
///glob.h
struct GlobalStruct
{
///char** ...
///
};
///glob.cpp
#include "glob.h"
struct GlobalStruct global;
///someOtherFile.cpp
#include "glob.h"
extern struct GlobalStruct global;
If you do not want to name a struct there's common method:
--- global.h: (file with global struct definition):
#ifdef GLOBAL_HERE /* some macro, which defined in one file only*/
#define GLOBAL
#else
#define GLOBAL extern
#endif
GLOBAL struct {
char **plymouthThemes;
char *plymouthTheme;
} global;
---- file1.c (file where you want to have global allocated)
#define GLOBAL_HERE
#include "global.h"
---- file2.c (any oher file referencing to global)
#include "global.h"
The macro GLOBAL is conditionally defined so its usage will prepend a definition with "extern" everywhere except source where GLOBAL_HERE is defined. When you define GLOBAL_HERE then variable gets non-extern, so it will be allocated in output object of this source.
There's also short trick definition (which set in single .c file where you allocate globals):
#define extern
which cause preprocessor to remove extern (replace with empty string). But do not do it: redefining standard keywords is bad.
The idea is that you need to declare only one but still need to define the variable in each other file that uses it. The definition includes both the type (in your case a header define structure - which therefore need include) and the extern keyword to let know the compiler the declaration is in a different file.
here is my example
ext.h
struct mystruct{
int s,r;
};
ext1.c
#include "ext.h"
struct mystruct aaaa;
main(){
return 0;
}
ext2.c
#include "ext.h"
extern struct mystruct aaaa;
void foo(){
aaaa;
}
ext3.c
#include "ext.h"
extern struct mystruct aaaa;
void foo2(){
aaaa;
}