Incomplete definition when using struct in header file - c

When I try to compile this program without the struct in the functions.h and functions.c file, it works. But when using a struct, it doesn't work.
How do I properly use structs with these .h and .c files?
main.c file
#include <stdlib.h>
#include <stdio.h>
#include "functions.h"
int main(void) {
func1();
func2();
//make a linked list of persons
person * head = NULL;
head = (person *) malloc(sizeof(person));
if (head == NULL) {
return 1;
}
head->val = 1;
head->next = NULL;
return 0;
}
functions.h file
struct node;
typedef struct node person;
void func1(void);
void func2(void);
functions.c file
#include "functions.h"
struct node {
char name;
int age;
node *next;
};
void func1(void) {
printf("Function 1!\n");
}
void func2(void) {
printf("Function 2!\n");
}
Compile it with:
gcc -o main.exe main.c functions.c

You can only use opaque types (incomplete types) when you don't need to know the size or 'contents' of the type — which means you can only use an opaque type when you only need pointers to the type. If you need the size, as in main() when you try to allocate enough space for a person, then you can't use an opaque type.
Either create an allocator function in functions.c, declare it in functions.h and call it in main.c, or define the type in functions.h for use in both main.c and functions.c.
In your code, the main() function also accesses members of the structure (head->val, head->next), so defining the type in functions.h is most appropriate.

Add to functions.h:
typedef struct node {
char name;
int age;
node *next;
} person;
to the functions.h did the trick as posted by Jonathan Leffler!
Remove from functions.h file:
struct node;
typedef struct node person;
Remove from functions.c file:
struct node {
char name;
int age;
node *next;
};

Related

using struct elements in function that is in another source file

New to learning c and I am having difficulties with writing a function in another source file that uses struct variables from the first source file.
basically I need to create a bubblesort function in another file to be used in my driver
this is what i am trying to do
driver.c
#include<stdio.h>
#include<stdlib.h>
#include<sort.c>
typedef struct iorb {
int base_pri;
struct iorb *link;
char filler[100];
} IORB;
int main(){
sort();
}
sort.h
void sortList(IORB * head, int(*prio)(int));
sort.c
void sortList(IORB * head, int(*prio)(int)){
// do stuff
}
but i get this error:
unknown type IORB in the sort function.
how can pass the IORB to the function ?
Updated code after trying the answer:
driver.c
#include<stdio.h>
#include<stdlib.h>
#include "sort.h"
#include "iorb.h"
//removed the typedef in the driver
iorb.h
#ifndef IORB_H
#define IORB_H
typedef struct iorb {
int base_pri;
struct iorb *link;
char filler[100];
} IORB;
#endif
sort.h
#ifndef SORT_H_
#define SORT_H_
void sortList(IORB * head, int(*prio)(int));
#endif
sort.c
#include "sort.h"
#include<stdlib.h>
#include<stdio.h>
#include "iorb.h"
void sortList(IORB * head, int(*prio)(int)){
//do stuff
}
You want to put your type declaration / typedef in a header file:
#ifndef IORB_H
#define IORB_H
typedef struct iorb {
int base_pri;
struct iorb *link;
char filler[100];
} IORB;
#endif
Then include that header file in sort.h:
#include "iorb.h"
and you want to include the sort.h in your sort.c:
#include "sort.h"

c headers and .c files with structures and typedefs

I am having a wonderful time, as usual. This time it has to do with header files, structures, and my .c files being used in some main. I've tried about every permutation that makes sense, and I can't get a proper link. This is just a permutation I've tried:
header file:
struct MyHashMap;
struct node;
typedef struct MyHashMap MyHashMap;
typedef struct node node;
struct MyHashMap* myHashMapCreate();
void myHashMapPut(MyHashMap* obj, int key, int value);
int myHashMapGet(MyHashMap* obj, int key);
void myHashMapRemove(MyHashMap* obj, int key);
void myHashMapFree(MyHashMap* obj)
HashMap.c:
#include "HashMap.h"
struct MyHashMap;
struct node;
typedef struct MyHashMap MyHashMap;
typedef struct node node;
struct node{
int key;
int val;
node* next;
};
struct MyHashMap{
node** hashTable;
};
MyHashMap* myHashMapCreate() {
}
void myHashMapPut(MyHashMap* obj, int key, int value) {
...
}
int myHashMapGet(MyHashMap* obj, int key) {
...
}
void myHashMapRemove(MyHashMap* obj, int key) {
...
}
void myHashMapFree(MyHashMap* obj) {
...
}
and the main file, some_application.c
#include "HashMap.h"
int main()
{
MyHashMap * obj = myHashMapCreate();
}
these typedefs keep trampling my includes. And creating errors for me such as:
HashMap.c: In function ‘myHashMapFree’:
HashMap.c:8:1: warning: empty declaration
8 | struct MyHashMap;
| ^~~~~~
HashMap.c:9:1: warning: empty declaration
9 | struct node;
| ^~~~~~
HashMap.c:11:26: error: storage class specified for parameter ‘MyHashMap’
11 | typedef struct MyHashMap MyHashMap;
It all makes sense to me, but the compiler and I are DEFINITELY not friends, yet. I don't know if we'll ever be friends. It's like that girl at the squash courts, I don't plan on stopping until something good, or bad happens.
Oh, and I tried compiling with:
gcc -o some_application some_application.c HashMap.c
As mentioned by Jonathan in the comments:
typedef struct MyHashMap MyHashMap;
typedef struct node node;
struct MyHashMap* myHashMapCreate(void);
void myHashMapPut(MyHashMap* obj, int key, int value);
int myHashMapGet(MyHashMap* obj, int key);
void myHashMapRemove(MyHashMap* obj, int key);
void myHashMapFree(MyHashMap* obj);
does suffice...

How to use structure from one c file in another [duplicate]

This question already has answers here:
How to use a defined struct from another source file?
(7 answers)
Closed 5 years ago.
is it posibble in C, that you define a structure in one .c file, but use it in another?
Basically, I would like to use my List that I have already created in another program. But I would like to use diffrent structures.
I've 3 files:
main.c -- another program, where I want to use the list
list.c -- code of the list
head.h -- header to bind them
In main.c:
#include <stdio.h>
#include <stdlib.h>
typedef struct cell{
int x;
cell next;
}TCell;
typedef struct{
TCell first;
int lenght;
}List;
#include "head.h"
int main()
{
TCell *c
c->x = 5;
List *l;
init(l);
add(l,c)
c = get();
return 0;
}
head.h:
#ifndef HEAD_H_
#define HEAD_H_
void init(List *l);
void add(List *l, TCell *c);
TCell get();
(...)
#endif
list.c
#include <stdio.h>
#include <stdlib.h>
#include "head.h"
typedef struct{
TCell first;
int lenght;
}List;
void init(List *l){ (...) }
void add(List *l, TCell *c) { (...) }
TCell get() { (...) }
(...)
But when i try to compile it, it doesn't work, because it is missing the TCell in head.h and list.c, and the List in head.h
So, is there a possibility to have just one definition of TCell in the main.c, so whenever i change its inner variables, it will still work?
Make this your head.h:
#ifndef HEAD_H_
#define HEAD_H_
typedef struct cell
{
int x;
cell next;
} TCell;
typedef struct
{
TCell first;
int lenght;
} List;
void init(List *l);
void add(List *l, TCell *c);
TCell get();
...
#endif
And remove the typedef of List and TCell from list.c and main.c, because you only need to define a type once.
Header files are meant to contain your shared type definitions.
Here's an entry of the famous C-FAQ that may help. I advise you to read through this whole FAQ it will teach you a lot of things about C and will save you a lot of time.

In C, how do you use a struct in the main function that was declared in a header file?

In C, I need to declare a struct linked list in a header file. Within the main of my .c file, how do I declare a new instance of my struct? Also should I use typedef for my struct?
In your header:
struct mystruct
{
int a;
int b;
};
in .c file include (#include "header.h") the header, then use in main:
struct mystruct obj1;
obj1.a=0;
obj1.b=0;
In your header file add the definition and typedef
typedef struct linked_list_node_st {
int val;
struct linked_list_node_st *next;
} Linked_List_Node;
In main.c, call the struct using the typedef.
#include <stdio.h>
#include <stdlib.h>
#include "structure.h"
int main(int argc, const char * argv[]) {
Linked_List_Node *node;
node = malloc(sizeof(Linked_List_Node));
node->next = 0;
node->val = 1;
return 0;
}
U have struct in header, and want that struct in main.c?
Just include it with #include "header.h" directive in your main.c, and start to use struct.
You use typedef when u want to make "your variable" in c, like:
typedef int INTEGER;
INTEGER number;
So u use typedef for closer indentify your struct, for you or for readers.

Conflicting types for 'Graph' error

I'm getting an error saying 'conflicting types for 'Graph' for the following code, but I'm not sure what the issue is, as Graph is declared before it is used anywhere. Anyone know what the issue is?
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define __USE_BSD // make prototype for strdup visible
#include <string.h>
typedef struct linkedlist { // linked list of ints (for use in Node)
int index;
struct linkedlist *next;
} List;
typedef struct { // a Node of a Graph
char *name;
List *outlist; // adjacency list
int outdegree; // length of outlist
int indegree; // length of inlist
int dfsnum;
//double pagerank_score; //not needed for this exercise
} Node;
typedef struct {
int MaxSize;
Node *table;
} Graph;
// use to check result of strdup, malloc etc.
extern void check (void *memory, char *message);
extern int initialize_graph (Graph *mygraph, int MaxSize);
extern int insert_graph_node (Graph *mygraph, int n, char *name);
extern int insert_graph_link (Graph *mygraph, int source, int target);
extern int read_graph (Graph *mygraph, char *filename);
extern void print_graph (Graph *mygraph);
I am not sure but i think CDT MinGW has an extended C lib which already has a variable name reserved which is called "Graph", have you tried renaming your struct? This might be the case though i have never worked with CDT MinGW before

Resources