So, out of the blue, the compiler decides to spit this in face:
"field customer has incomplete type".
Here's the relevant snippets of code:
customer.c
#include <stdlib.h>
#include <string.h>
#include "customer.h"
struct CustomerStruct;
typedef struct CustomerStruct
{
char id[8];
char name[30];
char surname[30];
char address[100];
} Customer ;
/* Functions that deal with this struct here */
customer.h
A header file for customer.h
#include <stdlib.h>
#include <string.h>
#ifndef CUSTOMER_H
#define CUSTOMER_H
typedef struct CustomerStruct Customer;
/* Function prototypes here */
#endif
This is where my problem is:
customer_list.c
#include <stdlib.h>
#include <string.h>
#include "customer.h"
#include "customer_list.h"
#include "..\utils\utils.h"
struct CustomerNodeStruct;
typedef struct CustomerNodeStruct
{
Customer customer; /* Error Here*/
struct CustomerNodeStruct *next;
}CustomerNode;
struct CustomerListStruct;
typedef struct CustomerListStruct
{
CustomerNode *first;
CustomerNode *last;
}CustomerList;
/* Functions that deal with the CustomerList struct here */
This source file has a header file, customer_list.h ,but I don't think its relevant.
My Problem
In customer_list.c, at the line with the comment /* Error Here */, the compiler complains about field customer has incomplete type.
I've been googling this problem all day, and now im at the point of pulling out my eyeballs and blending them with strawberries.
What is the source of this error ?
Thanks in advance :)
[P.S. if I forgot to mention something, let me know. Its been a stressful day for me, as you might tell ]
Move the struct declaration to the header:
customer.h
typedef struct CustomerStruct
{
...
}
In C, the compiler needs to be able to figure out the size of any object that is referenced directly. The only way that the sizeof(CustomerNode) can be computed is for the definition of Customer to be available to the compiler when it is building customer_list.c.
The solution is to move the definition of the struct from customer.c to customer.h.
It seems that something like
typedef struct foo bar;
won't work without the definition in the header. But something like
typedef struct foo *baz;
will work, as long as you don't need to use baz->xxx in the header.
What you have is a forward declaration of Customer structure that you are trying to instantiate. This is not really allowed because compiler has no idea about the structure layout unless it sees it definition. So what you have to do is move your definition from the source file into a header.
Related
I have several structures, and I keep getting a warning message. I've been trying for several hours to kick it out, but I can't.
I would really appreciate the help.
This is the Student struct in the Student.h header:
#ifndef __STUDENT_H__
#define __STUDENT_H__
#include "Teacher.h"
#include "ClassRoom.h"
struct Teacher;
struct ClassRoom;
typedef struct {
char * name;
struct ClassRoom *myClassRoom;
struct Teacher *myTeachers[3];
} Student;
void setTeacherDynamic(struct Teacher *t, struct Teacher* tt);
and this is the Student.c source code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Teacher.h"
#include "Student.h"
struct Teacher;
void setTeacherDynamic(Teacher *t, Teacher* tt)
{
strcpy(t->name, tt->name);
t->myClass = NULL;
}
The warning message is:
The problem is with the function setTeacherDynamic(), and I don't know how to fix it.
The Teacher struct:
and this is when I'm calling to the function, also in Student.c
You have multiple problems:
The first is that since you have forward declarations in Student.h you don't need to include Teacher.h or ClassRoom.h. And in the source file Student.c you can remove the forward declaration you have.
The second problem is that you don't actually have a struct Teacher. You have a Teacher type-alias for an anonymous structure. You should declare the actual structure for the forward declarations to work:
typedef struct Teacher { ... } Teacher;
You should do these changes for all your source and header files.
I'm new to header files and am not sure why I am getting this error. The first piece of code is from the relevant header file, and gives the expected identifier error:
#define MAX_ADDR_LENGTH 1000
struct listNode{
char addr[MAX_ADDR_LENGTH];
struct listNode *next;
};
Related to this, there is another error in the file relevant to that header, which gives me a "note: in expansion of macro 'MAX_ADDR_LENGTH', which it gives me on the line which gives the declaration of int MAX_ADDR_LENGTH:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
char *crawl(char* getLinksFrom, int hopTo){
int MAX_ADDR_LENGTH = 300;
char startAddr[MAX_ADDR_LENGTH];
char destAddr[MAX_ADDR_LENGTH];
}
I've tried a number of things hoping it was just a small oversight (removed the #define altogther, deleted the line that gives the int MAX_ADDR_LENGTH declaration, just deleted the phrase 'int' from the same; all of which just caused even more errors).
The problem: ‘MAX_ADDR_LENGTH’ is defined twice in your code; Once as a Macro and once as a variable.
Try to delete the statement declaring MAX_ADDR_LENGTH as a variable.
Build your header like this:
#ifndef HEADER_H
#define HEADER_H
#define MAX_ADDR_LENGTH 1000
typedef struct _listNode{
char addr[MAX_ADDR_LENGTH];
struct _listNode *next;
} listNode;
#endif /* HEADER_H */
and use it like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
char *crawl(char* getLinksFrom, int hopTo){
char startAddr[MAX_ADDR_LENGTH];
char destAddr[MAX_ADDR_LENGTH];
.... more code
}
The #ifndef...#endif construct is called an include guard. It's not necessary to get your code compiled, but good practice to use it.
The typedef is used to define the node structure. It does not create a variable yet, it's just defining a type named listNode that you can use to build your list later on.
I have a problem with my struct definition.
I define it here:
#ifndef CHALLENGE_SYSTEM_H_
#define CHALLENGE_SYSTEM_H_
#include "visitor_room.h"
typedef struct SChallengeRoomSystem
{
#include "challenge_room_system_fields.h";
} ChallengeRoomSystem;
#endif
And the file "challenge_room_system_fields.h" is:
#ifndef CHALLENGE_ROOM_SYSTEM_FIELDS_H_
#define CHALLENGE_ROOM_SYSTEM_FIELDS_H_
#include "visitor_room.h"
struct VisitorList {
Visitor* visitor;
struct VisitorList* next;
};
struct VisitorList* list;
char *name;
int num_of_challenges;
Challenge* challenges;
int num_of_rooms;
ChallengeRoom* rooms;
int last_time;
#endif
The following code gives me the error: "error C2016 C requires that a struct or union has at least one member". I don't understand why it doesn't work because I did declare members in the struct.
P.S. It's part of my homework and I have to define the members of the struct in the "challenge_room_system_fields.h" file. Also, "visitor_room.h" is another file in this project but it's not the reason of the problem for sure.
I'm getting "Error: storage size of 'c' isn't known" when i try to create the variable "c" of my struct called "struct car"
Here is the code:
teste.h
#ifndef TESTE_H_INCLUDED
#define TESTE_H_INCLUDED
typedef struct car Car;
#endif // TESTE_H_INCLUDED
teste.c
#include <stdio.h>
#include <stdlib.h>
#include "teste.h"
struct car{
char name[20];
char model[20];
};
main.c
#include <stdio.h>
#include <stdlib.h>
#include "teste.h"
int main()
{
Car c;
return 0;
}
I can't figure out why I'm getting this error... I bet it is something stupid... could someone help me?
the Car structure on the header file is just a forward declaration, when it's included on main.c, it only has knowledge of the forward declaration but no clue of how it's defined (or in this case, what the size of the struct is). define your struct on the header file.
struct car {
char name[20];
char model[20];
};
Header file declaration:
typedef struct Queue *QueueP;
C File implementation:
struct Queue
{
char *head;
char *tail;
QueueItemT item; //char typedef from the header file, not what's giving error
int SizeL;
int sizeP;
int QueueSize;
};
C main file:
#include <stdio.h>
#include <stdlib.h>
#include "Queue1.h"
int main()
{
struct Queue queue;
QueueP myQueue = &queue;
return 0;
}
I am getting errors on the following lines with the following messages respectively:
struct Queue queue;
^
Main : variable has incomplete type 'struct Queue'
typedef struct Queue *QueueP;
^
Header : note: forward declaration of 'struct Queue'
Any idea what might be causing these errors? I'm new to working with multiple files and header files in C, so I'm really having trouble wrapping my head around these errors. Any help would be great, thanks!!
You put structure definition into a c file. This is not how it works: you need to put the definition into the header.
This is because a definition of a struct is not an implementation. C compiler needs this information in order to process declarations of the struct correctly. A forward declaration lets you define a pointer to your struct; declaring a struct itself requires a full definition.
If you would like to keep the details of your struct private, put it into a private header file. Include the public header file from your private header, too:
queue.h
typedef struct Queue *QueueP;
queue_def.h
#include "queue.h"
struct Queue
{
char *head;
char *tail;
QueueItemT item; //char typedef from the header file, not what's giving error
int SizeL;
int sizeP;
int QueueSize;
};
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "queue_def.h"
Now your project should compile without problems.
Actually, the reason I was getting forward declaration problems was because I was trying to access the struct (that was declared in the .c file) from within the main file.
Not only was this bad programming practice, the desired feature of the project was that the end user (i.e. the person using the interface and implementation to build their 'main.c' file) should have no idea what kind of struct was being used, they should simply be able to build a queue with the functions given and not know what was going on behind the scenes.
D'oh!!!