How to use a defined struct from another source file? - c

I am using Linux as my programming platform and C language as my programming language.
My problem is, I define a structure in my main source file( main.c):
struct test_st
{
int state;
int status;
};
So I want this structure to use in my other source file(e.g. othersrc.). Is it possible to use this structure in another source file without putting this structure in a header?

You can define the struct in each source file, then declare the instance variable once as a global, and once as an extern:
// File1.c
struct test_st
{
int state;
int status;
};
struct test_st g_test;
// File2.c
struct test_st
{
int state;
int status;
};
extern struct test_st g_test;
The linker will then do the magic, both source file will point to the same variable.
However, duplicating a definition in multiple source files is a bad coding practice, because in case of changes you have to manually change each definition.
The easy solution is to put the definition in an header file, and then include it in all the source file that use the structure. To access the same instance of the struct across the source files, you can still use the extern method.
// Definition.h
struct test_st
{
int state;
int status;
};
// File1.c
#include "Definition.h"
struct test_st g_test;
// File2.c
#include "Definition.h"
extern struct test_st g_test;

You can use pointers to it in othersrc.c without including it:
othersrc.c:
struct foo
{
struct test_st *p;
};
but otherwise you need to somehow include the structure definition. A good way is to define it in main.h, and include that in both .c files.
main.h:
struct test_st
{
int state;
int status;
};
main.c:
#include "main.h"
othersrc.c:
#include "main.h"
Of course, you can probably find a better name than main.h

// use a header file. It's the right thing to do. Why not learn correctly?
//in a "defines.h" file:
//----------------------
typedef struct
{
int state;
int status;
} TEST_ST;
//in your main.cpp file:
//----------------------
#include "defines.h"
TEST_ST test_st;
test_st.state = 1;
test_st.status = 2;
//in your other.ccp file:
#include "defines.h"
extern TEST_ST test_st;
printf ("Struct == %d, %d\n", test_st.state, test_st.status);

Putting it in a header file is the normal, correct way to declare types shared between source files.
Barring that, you can treat main.c as a header file and include it in the other file, then only compile the other file. Or you can declare the same struct in both files and leave a note to yourself to change it in both places.

C supports separate compilation.
Put the structure declaration in a header file and #include "..." it in the source files.

It is perfectly reasonable to be inclusive with structs by leaving them in the source file instead. This is encapsulation. However if you're going to redefine struct multiple times in multiple source files then you might as well define the struct once in a header file instead and include that file as necessary.

Header file /* include this header file in both file1.c and file2.c
struct a {
};
struct b {
};
so header file included the declaration of both structures .
file 1.c
struct a xyz[10]; --> struct a defined here
to use struct b here in this file
extern struct b abc[20];
/* now can use in this file */
file2.c
struct b abc[20]; /* defined here */
to use struct a defined in file1.c
use extern struct a xyz[10]

Related

Proper way to declare and use structures in C project?

I am building a project that I am trying to organize as follows:
main.c
globals.h
structures.h
FunctionSet1.c, FunctionSet1.h
FunctionSet2.c, FunctionSet2.h
etc.
I thought I could define a structure type in structures.h:
struct type_struct1 {int a,b;}; // define type 'struct type_struct1'
then declare a function1() returning a structure of type type_struct1 in FunctionSet1.h:
#include "structures.h"
struct type_struct1 function1(); // declare function1() that returns a type 'struct type_struct1'
then write function1() in FunctionSet1.c:
#include "FunctionSet1.h"
struct type_struct1 function1() {
struct type_struct1 struct1; // declare struct1 as type 'struct type_struct1'
struct1.a=1;
struct1.b=2;
return struct1;
}
Edit: with the corrected code above, the compiler returns
306 'struct' tag redefined 'type_struct1' structures.h
Is the file set good practice ?
What is the good practice to manage the structures ?
In your example, you declare a structure named type_struct in structure.h, then in FunctionSet1.h the structure that you are returning is type_struct, and in the .c it is called struct1.
So i think that the problem is that struct1 and type_struct are not recognized because they have never been defined ...
However, the organization of your files is fine.
Your general structure looks good. One thing you need to do, as zenith mentioned, is to put include guards into your header files. What that is is a set of #define's that make sure that the contents of the header are not included more that once in a given file. For example:
structures.h:
#ifndef STRUCTURES_H
#define STRUCTURES_H
struct type_struct1{
int a,b;
};
...
// more structs
...
#endif
FunctionSet1.h:
#ifndef FUNCTION_SET_1_H
#define FUNCTION_SET_1_H
#include "structures.h"
struct type_struct1 function1();
...
// more functions in FucntionSet1.c
...
#endif
main.c:
#inlcude <stdio.h>
#include "structures.h"
#include "FunctionSet1.h"
int main(void)
{
struct type_struct1 struct1;
struct1 = function1();
return 0;
}
Here, main.c includes structures.h and FunctionSet1.h, but FunctionSet1.h also includes structures.h. Without the include guards, the contents of structures.h would appear twice in the resulting file after the preprocesser is done. This is probably why you're getting the "tag redefined" error.
The include guards prevent these type of errors from happening. Then you don't have to worry about whether or not a particular header file was included or not. This is particularly important if you're writing a library, where other users may not know the relationship between your header files.
First of all, you have to declare the structure in your file.h (you can use typedef to create an alias)
typedef struct Books
{
char title[50];
int book_id;
} books;
then, you have to include your file.h in your file.c and declare your variable like this
#include "file.h"
int main()
{
books book1;
book1.title = "Harry Potter";
book1.book_id = 54;
}
or like this if you didn't use typedef
#include "file.h"
int main()
{
struct Books book1;
book1.title = "Harry Potter";
book1.book_id = 54;
}
Thank you all.
I read again what you said and found that the code above is now correct.
The error I report is with testing the following main.c
#include "structures.h"
#include "FunctionSet1.h"
void main() {
struct type_struct1 struct2;
struct2=function1();
}
in which structures.h is included again, thus causing the error. Removing the include eliminates the error.
I will now look into header guards to avoid such problems.
Thanks again.

Error : multiple definition

I am writing a kernel module in which i have 3 source files and one header file. When I compile it, it shows me the following error:
/home/karan/project/proc.o: In function `proc_read':
/home/karan/project/proc.c:23: multiple definition of `info'
/home/karan/project/main.o:/home/karan/project/main.c:23: first defined here
/home/karan/project/tx_pkt.o: In function `tx_packet':
/home/karan/project/tx_pkt.c:9: multiple definition of `info'
/home/karan/project/main.o:/home/karan/project/main.c:23: first defined here
I think the problem is the compiler is taking definition struct info more then once. But what is the solution? The struct info is declared in the header file . The header file is as follow:
int proc_write(struct file *filp,const char *buffer,unsigned long count,void *data);
int proc_read(char *buffer,char **buffer_location,off_t offset,int buffer_length,int *eof,void *data);
void tx_packet(void);
#ifndef MYDEFS_H
#define MYDEFS_H
struct inform
{
char tx_buffer[100];
struct iphdr *ip1;
};
extern struct inform info;
#endif
Use : header guards
In your header do this:
#ifndef MYDEFS_H
#define MYDEFS_H
struct info {
...
...
};
#endif
I think You added the main .c file in ($(USERAPPS): $(USERSP) $(CC) -o $# ) here,
U include all c file except main file here

How to forward typedef'd struct in .h

I have
Preprocessor.h
#define MAX_FILES 15
struct Preprocessor {
FILE fileVector[MAX_FILES];
int currentFile;
};
typedef struct Preprocessor Prepro;
void Prepro_init(Prepro* p) {
(*p).currentFile = 0;
}
I realized then that I had to separate declarations from definitions. So I created Preprocessor.c:
#define MAX_FILES 15
struct Preprocessor {
FILE fileVector[MAX_FILES];
int currentFile;
};
typedef struct Preprocessor Prepro;
And Preprocessor.h is now:
void Prepro_init(Prepro* p) {
(*p).currentFile = 0;
}
That obviously, doesn't work because Pr..h doesn't know Prepro type. I already tried several combinations, none of them worked. I can't find the solution.
Move the typedef struct Preprocessor Prepro; to the header the file and the definition in the c file along with the Prepro_init definition. This is will forward declare it for you with no issues.
Preprocessor.h
#ifndef _PREPROCESSOR_H_
#define _PREPROCESSOR_H_
#define MAX_FILES 15
typedef struct Preprocessor Prepro;
void Prepro_init(Prepro* p);
#endif
Preprocessor.c
#include "Preprocessor.h"
#include <stdio.h>
struct Preprocessor {
FILE fileVector[MAX_FILES];
int currentFile;
};
void Prepro_init(Prepro* p) {
(*p).currentFile = 0;
}
If you want to hide the definition of Preprocessor, you can simply put this in the header file :
struct Preprocessor;
typedef struct Preprocessor Prepro;
But more generally, you'll probably also need the Preprocessor definition in the header file, to allow other code to actually use it.
You have put in .c what should be in .h, and vice versa. Prepro_init must be in .c file, and that file must #include "Preprocessor.h".
YAS:Yet Another Solution.
Preprocessor.h
<some code>
void Prepro_init(Prepro* p) {
(*p).currentFile = 0;
}
<some code>
Preprocessor.c
#define MAX_FILES 15
struct Preprocessor {
FILE fileVector[MAX_FILES];
int currentFile;
};
typedef struct Preprocessor Prepro;
#include "Preprocessor.h" //include after defining your structure.
<some code>
{
struct Prepro p;
Prepro_init(p);
<some code>
.... using p.currentFile.....
.....using other members....
<some code>
}
<some code>
Now it will work. I think this is your requirement. Hope it helps.
Drawback:
The members of the structure Preprocessor, must be predetermined. i.e the header file uses the member currentFile. So, c file which includes Preprocessor.h must have a structure which is typedefined as Prepro and that structure must include a member currentFile.(in this case).
The same problem I had a year before, while writting a header file to display a users Avl tree in a graphical tree format.
I would suggest that you follow Linus[1], and do not use typedef struct.
If you are in control over the library:
Include file
struct Foo;
int foo_get_n(const struct Foo *bar);
In implementation file
struct Foo
{int n;};
int foo_get_n(const struct Foo *bar)
{return bar->n;}
If you are not in control over the library:
Ask the maintainer to remove these polluting typedefs from the include files.
Summary
Do not use typedef struct.
[1] http://yarchive.net/comp/linux/typedefs.html
Swap .h and .c file. Include header in .c.
Also refer to a book about declarations, definitions and what header files do.

How to access a structure defined in a header file from an implementation file?

How do you access a struct say struct common, that is defined in a header file, in a .c file? We'll include the header file in the .c file and then can we directly use
struct common C;?
header file-new_algo.h
#ifndef NEW_ALGO_H_
#define NEW_ALGO_H_
#endif /* NEW_ALGO_H_ */
struct common{
float count;
//other variables
};
main.c
#include "new_algo.h"
int main()
{
typedef struct common myStruct;
myStruct* S;
S->count = 0;//when I do this segmentation fault occurs
//this is the error I get in eclipse
/* Thread [1] 0 (Suspended : Signal : SIGSEGV:Segmentation fault)
main() at E:/Namratha//trial/.settings/..\\src\\main.c:44 0x401443*/
}
Hey, the fault error is not resulted from access control.
Before use struct varible, you should malloc space for it like
myStrcut *s = (myStrcut *)malloc(sizeof(myStruct))
then assign:
s->count = 0
Please have a try.
Yes, it's correct. Just include the header in the source file and create the instance for the struct.
header.h
struct common
{
// ...
};
.c
#include "header.h"
struct common C ;

extern without type

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;
}

Resources