About accessing structs defined in different source file - c

Not any homework, but seem to have got lost while doing basics, hence asking.
Say I have 2 C source files. 1.c & 2.c
2.c is as follows:
typedef struct mystr_
{
int a;
float b;
}mystr;
void fun()
{
mystr q;
some code....
}
And 1.c is as below:
#include "stdio.h"
void fun();
main()
{
//How to access / declare a variable of type mystr here.
mystr *v1;//This obviously gives compiler errors
some code....
}
How to access the structure mystr defined in 2.c from file 1.c to have variables of that struct type there?
EDIT:
Sorry forgot to mention in OP. I cannot move the declaration out in a header file for some reason --> It is a quick hack that I am trying to check in a existing code. Then is there any way to access it directly from the other source file?

Use headers.
Create a file 2.h
typedef struct mystr_
{
int a;
float b;
}mystr;
And include it in 1.c
#include "2.h"
#include "stdio.h"
void void fun();
EDIT:
Because you are not able to extract the declaration into a header file and include it, there is no other way than copying the declaration. This is a highly fragile construct, quick but mainly dirty and not really recommended unless you are out of other options.

Related

Understanding structs in C

I just started learning C.
I have the following code:
#include <stdio.h>
void func(struct Foo foo){
foo.x =1;
foo.array[3] =2;
}
int main(){
struct Foo lol;
lol.x = 55;
lol.array[3] = 67;
func(lol);
printf("lol.x is %d and lol.array[3] is %d\n", lol.x, lol.array[3]);
return 0;
}
But when I compile it I get the following errors
structs.h:3:22: error: variable has incomplete type 'struct Foo'
void func(struct Foo foo){
structs.h:10:13: error: variable has incomplete type 'struct Foo'
struct Foo lol;
I looked it up and a lot of times the problem is in not defining structs in .h file. I defined it in a separate .h file, didnt help. I defined structs on the top of .c file, same errors.
I added this to the top of the file:
typedef struct Foo{
int x;
int array[3];
}Foo;
Can someone explain why its happening?
I looked it up and a lot of times the problem is in not defining structs in .h file. I defined it in a separate .h file, didnt help.
If you defined struct in separate .h file that you should include that file in this code.
#include <stdio.h>
#include "your_file.h"
....
From edit some other problem (UB)-
foo.array[3] =2; //you can't access index 3, declaration in struct is int array[3].
You are seeing a compilation time error, since struct Foo foo cannot evaluate the type. You have to declare the structure before using it.
You can include the header file or just write the following lines above func definition.
struct FOO
{
int x;
int array[n]; // n>3
};

Returning struct from different file in C

Lately I've encountered a problem of returning struct from another file in C language.
Here's the code of main.c:
#include <stdio.h>
#include <stdlib.h>
#include "hash_types.h"
int main()
{
hashinfo info;
info = numerator();
printf("%d\n", info.ppower);
return 0;
}
And numerator.c:
#include <stdlib.h>
#include <stdio.h>
#include "hash_types.h"
hashinfo numerator()
{
hashinfo info;
info.ppower = 15;
return info;
}
Here's what header file looks like:
typedef struct hashinfo{
unsigned long a_str;
unsigned long a_int;
unsigned long b_int;
unsigned long p;
unsigned long m;
char w;
char ppower;
}hashinfo;
When I try to compile the code, gcc fails to compile main reporting that
main.c: In function ‘main’:
main.c:10:7: error: incompatible types when assigning to type ‘hashinfo’ from type 'int'
info = numerator();
^
If I put all of these in the one file and compile, it will work just fine. What am I doing wrong? Thanks in advance.
You have to declare your numerator function everywhere where you want to use it. This is what the minimal declaration would look like
hashinfo numerator();
But a better idea would be to declare it with prototype
hashinfo numerator(void);
and do the same thing in the definition.
A typical approach would be to put the declaration into a header file and include it everywhere you what to use this function. Whether your hash_types.h is the appropriate one is for you to decide.
You have no way to telling your main what numerator() returns without including it somehow. It's generally considered bad practice to include a .c file, but try to add #include "numerator.c" to the top of main.c to see.
Add the declaration for numerator() in the header file hash_types.h. Add this at the end of hash_types.h: hashinfo numerator();
So how do you think that the main.c part (top) would know what type that numerator() returned? How would you inform main.c that it will reference functions of specific signatures? Potentially, you could create a separate file containing nothing but prototypes for your functions and have all modules include it. "proto.h" or similar.
Mark

Using structs in multiple files

I am trying to call a function in main.c from io.h that reads data from a file, stores that data into multiple structs, then somehow lets me pass the different structs as arguments in later functions in main. Those later functions will be defined in other files, such as alg.h.
How do I go about doing this? Do I use extern and make the structs global and put them in a separate file? Is it possible to have a function from alg.h have a return type of one of the structs? Does it depend on the order of my includes?
The code pasted below complies and works, but any attempt to move either of the structs causes the program to not compile.
Also, is it possible to have, for example, a struct declared in alg.h, then functions that have that struct as a parameter declared later in alg.h. Then in main.c, you initialize and pass the struct into a function declared in io.h, give the struct some values, have it returned to main.c, then pass that into the function declared in alg.h? I know that sounds like a class, but I need a C solution and I only need one instance of the struct floating around.
Thanks.
io.h
struct s1 {
int num1;
double num2;
};
struct s2 {
int num3;
double num4;
};
void io_init(struct s1*, struct s2*);
io.c
#include <stdio.h>
#include <stdlib.h>
#include "io.h"
void io_init(struct s1* s1i, struct s2* s2i)
{
s1i->num1 = 5;
s1i->num2 = 2.4;
FILE *fp;
char line[80];
fp = fopen("input.txt","rt");
fgets(line, 80, fp);
sscanf(line,"%i",&s2i->num3);
fgets(line, 80, fp);
sscanf(line,"%i",&s2i->num4);
fclose(fp);
}
alg.h
void ga_init(struct s1);
alg.c
#include <stdio.h>
#include "io.h"
#include "ga.h"
void ga_init(struct s1 s1i)
{
printf("%i", s1i.val1);
}
main.c:
#include <stdio.h>
#include "io.h"
#include "ga.h"
int main() {
struct s1 s1i;
struct s2 s2i;
io_init(&s1i, &s2i);
ga_init(s1i);
return 0;
}
Every file which requires the declaration of your types (i.e., wants to use them) must include your header file (ok, so forward declarations and pointers will work, but they can't be dereferenced without the definition and that's not really applicable here anyway.)
So, to elaborate, if file X needs to use struct Y then it needs to include the header file which contains its declaration, that's it.
/* X.c */
#include "Y.h" /* <-- that's it! */
void foo(Y *obj) {
/* ... */
}
Here is some advice.
Your .h file is not defining struct objects. It's just defining the type. It's fine the way it is. Everyone who touches any struct of those types should include this file.
It's very rare to need to pass a struct by value as you are doing in the call to ga_init. You will essentially always want to call by reference, like you did with io_init.
Yes, you can return a struct, but again, it would almost always be better to return a reference to a struct.
You can certainly share globally defined structs and you don't need extern unless your linker is something awful. But sharing a reference to a struct allocated in main() amounts to roughly the same thing.

issues with structure with a pointer to it in a header file in c

`"a.h"
typedef struct a
{
File* fp;
int var;
};
extern a *pp;
---------------------
"a.c"
int show(a* ptr)
{
printf("%d",ptr->var); //ptr has no member named var
}
---------------------
"main.c"
#include"a.h"
main()
{
a *pp=(a*)malloc(sizeof(a));
printf("%d",pp->var);// pp has no member named var
show(pp);
}
in the two print statements above, it gives me an error that a certain member of the struct is not present. did i miss anything? is there something i must do in addition?
i have a situation like this- very similar, not exact. please help. it is very important and i dont have much time.
That won't even compile, let alone run. You have do active definition for a in a.c, your typedef is incomplete, File should be FILE (and you should include stdio.h), and that's about where I stopped reading and started rewriting. If you post code to demonstrate a problem, make sure you post the right code, not just something you made up :-)
If you want a working solution to start with, go for a.h:
#include <stdio.h>
typedef struct {
FILE* fp;
int var;
} a;
and a.c:
#include "a.h"
int show(a* ptr) {
printf ("%d\n", ptr->var);
}
and, finally, main.c:
#include <stdio.h>
#include <stdlib.h>
#include"a.h"
int main (void) {
a *pp = malloc (sizeof (a));
printf ("%d\n", pp->var);
show (pp);
return 0;
}
Those will at least compile at which point you can begin the debugging process.
In a.c you forgot to include a.h so that the definition of the structure is not available.
Even though you have declared a variable pp, you forgot to actually define it. See External Variable.
On a side note - do not use typedef with structures where it is not necessary (i.e. the type is supposed to be an opaque type). C programmers like things to be clear and explicit. If it is a structure, a "struct" hint is very much appreciated and is worse a bit more typing.
Also, the "main" function must return an integer result code, preferably EXIT_SUCCESS or EXIT_FAILURE (defined in stdlib.h).
Try:
typedef struct
{
File* fp;
int var;
} a;

Error: In C, got the error "dereferencing pointer to incomplete type" in a struct pointer

Hello Everybody!
I got the following error, while trying to test a code for the game Clever Frog:
error: dereferencing pointer to incomplete type
The 'full code' is at pastebin.com - here (won't expire). But I think that with the explanation below, anybody can understands. Note: I haven't implemented yet the function that will erase the allocated memory and other things.
I have a struct defined in a 1.c file:
#include "1.h"
...
struct test {
int a;
};
...
I have a 1.h wicth have the typedef using it:
...
typedef struct test testT;
...
Then I have a function that has a parameter in it depending on testT, wich is in 2.c:
...
void funcTest(testT **t, int *size, ..){
/* another function that creates mem.space/alocate memory based enter code here`on the need of size above */
createMem(t,*size); /* void createMem(testT **t, int size); */
t[0]->a = 0; /*ERROR HERE*/
/* ... more code ... */
}
...
The 2.h file is like this:
...
void funcTest(testT **t, int *size, ..);
...
I will pass a testT *var as the way below, at the main programam:
...
testT *varTest; int size;
funcTest(&varTest, &size);
...
The bizarre thing is that the code compile when I use struct test at 1.h file (removing struct test from 1.c - which is wrong). But, when running the compiled program, exactly where the error occurs is the place of t[0]->a.
I already tried 'everything' but nothing worked :( I have faith that is something very stupid, so if anybody knows something, please tell me :D
Thanks!
When you try to access the a member of the t[0] struct the compiler needs to know how this struct looks like (for example to see if there even is any a member in it). Since you didn't put the struct test type definition anywhere where the compiler can see it when compiling 2.c, you get an error. The compiler doesn't know what a struct test contains.
If you put the definition of the struct test in 1.h, the compiler sees how that type looks like and can use the struct members.
Just put the complete type definition in 1.h, that's where it's supposed to be.
Somewhere you have a preprocessed file that has
typedef struct test testT;
Which doesn't include
struct test {
int a;
};
Preprocessing inlines all the #includes directives. As long as you were only using a testT pointer, the compiler would have known to "allocate a pointer's worth of memory" and the compilation would have progressed further than expected.
When you actually try to use that pointer to dereference something, the compiler would then realize it NEEDED the full definition of "struct test" and you would get the error displayed.
If you want the struct to be usable both in 1.c and 2.c, it must be defined in a header file that is visible to both. I don't know why you say that this is "wrong", it's common practice and AFAIK there is no other way around that directly.
If it's only defined in 1.c, then the compiler has no idea if struct test has a member named "a" when processing 2.c.
Another option is to just keep the forward declaration as you have now, but also include accessor/mutator functions in the header. Then 2.c does not have to know about the "internals" of struct test, but can act on it. This is also very common in C APIs.
(You could also define the struct identically both in 1.c and 2.c but that's a very bad idea.)
The definition of struct Test is only visible inside the file 1.c. The code t[0]->a doesn't see that this struct has a member named a. The types shared between several compile units shuld be defined in a header!
You should know that C/C++ compiles each .c file separately, so it has no way to know that the structure is defined in some other .c file.
You should perhaps do the following:
(1.h)
struct test {
int a;
};
...
(1.c)
#include "1.h"
...
(2.c)
#include "1.h"
...
void funcTest(testT **t, int *size, ..){
createMem(t,*size); /* void createMem(testT **t, int size); */
t[0]->a = 0;
/* ... more code ... */
}
But, when running the compiled program, exactly where the error occurs is the place of t[0]->a.
The pointer to the allocated memory is actually in *t, not t (as seen from your createMatrix code at Pastebin), so you should really be doing:
(*t)[0].a
and similarly in your for loop:
(*matriz)[i].row

Resources