Extern structure logic - c

How to extern structure in c language. So that I can use into another structure.

I'm assuming b is another source file. You can so something like:
file: file.h
#ifndef _FILE_H_
#define _FILE_H_
struct emp {
char name[100];
};
#endif
file: a.c
#include "file.h"
extern struct emp e; // declare struct var as extern.
int main() {
printf("Name = %s\n",e.name);
return 0;
}
file: b.c
#include "file.h"
struct emp e = {"stackoverflow"}; // struct var defined here.
On running:
$ gcc *.c && ./a.out
Name = stackoverflow
You question is very unclear and you are not new on SO.

Extern struct works as well as extern, at least when the extern is in the header file and the actual struct is in a cpp file that includes that header. I don't think "extern struct" is necessary so much as just "extern".

Related

Why does my C project compilation cannot find my structure?

I had a project based on a single C file that I try to rearrange for further development in several .c and .h files.
My main is organised as follow:
// General includes
typedef struct
{
} MyStruct;
#include "MyInclude.h"
// Rest of the code
My file "MyInclude.c" is organised as follow:
#include "MyInclude.h"
// Defines
// Functions that need to know MyStruct
There is something I don't understant about the compilation process of GCC. In fact, I got the error "MyStruct undeclared (first use in this function)" and I don't why as I put my include after the typedef declaration of my structure.
Does someone knows why it happens?
The question is a bit unclear.
The file "MyInclude.c" can access only to your H file.
While your struct is written in another C file.
You can solve it by:
Define the struct on the H file "MyInclude.h". It will work, but methodologically it's wrong.
Define setters and getters to access your struct
Cheers
Your file.h :
// file.h
#include <stdio.h> //Juste for printf
typedef struct s_data
{
char c;
} t_data;
Your file.c :
#include "file.h"
int main()
{
t_data data;
data.c = 'a';
printf("%c", data.c);
return (0);
}
Compil (if your file .c and .h are in the same directory):
gcc file.c -o my_app -I .

C - unknown type name (global struct)

I have a file a.h which defines the structure:
typedef struct q_elem_s
{
def_task task;
struct q_elem_s *next;
} q_elem;
def_task is a structure in a second file b.h.
typedef struct task_s
{
int id;
int length;
} def_task;
Now my compiler says that def_task task inside q_elem_s is unknown?
a.c includes b.h. What is the problem then?
a.h should include b.h
Strange, I have another version of this code and it worked without
this.
When it worked without a.h including b.h, it probably did because a.c (or whatever main file) included b.h before a.h.

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.

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

How to use a defined struct from another source file?

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]

Resources