I'm very new to structs in C and I'm trying to write a program using a couple of structs and a main .c file. I'm trying to create a Create in the struct that returns a pointer to the struct for my main file to deal with.
However, every time I get the following error:
expected '=', ',', ';', 'asm' or '_attribute__' before 'createCust'
Customer createCust(...) { (with the carat at the beginning of createCust).
here are the relevant code snippets:
customer.h
#ifndef CUSTOMER_H
#define CUSTOMER_H
#include "order.h"
typedef struct customer *Customer;
Customer createCust(...);
void addOrder(...);
#endif
And customer.c:
#include "customer.h"
#include "order.h"
#include <stdio.h>
#include <string.h>
Customer createCust(...);
struct customer {
int customerNum;
char name[20];
order orders[20];
int index;
int capacity;
}
Customer createCust(int id, char nam[]) {
Customer c = malloc(sizeof(struct customer));
// other stuff
return c;
}
I am also getting another error about how order is an unknown type despite having included order.h in my file.
#ifndef ORDER_H
#define ORDER_H
typedef struct order *Order;
Order create(...);
#endif
You're missing a semicolon at the end of the struct's declaration, i.e.:
struct customer {
int customerNum;
char name[20];
order orders[20];
int index;
int capacity;
};
Related
Suppose I have such a project structure:
main.c
#include "hashtable.h"
#include "list.h"
int main()
{
hash_table ht = calloc(1, sizeof(htable));
cmp_function f;
TLDI list;
return 0;
}
hashtable.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _HASH_TABLE_
#define _HASH_TABLE_
#include "list.h"
typedef int (*hash_function)(void*, int);
typedef struct _hasht_{
int maxElemNumber;
hash_function hf;
TLDI* key_array;
} htable, *hash_table;
void test2(cmp_function cmp);
#endif
list.h
#include "hashtable.h"
#ifndef _LINKED_LIST_
#define _LINKED_LIST_
typedef int (*cmp_function)(void*, void*);
typedef struct _node_ {
void *info;
struct _node_ *pre, *urm;
} TNode, *TLDI;
int test(hash_table ht);
#endif
and another two C files:
hash_func.c
#include "hashtable.h"
void test2(cmp_function cmp)
{
printf("test\n");
}
list_func.c
#include "list.h"
int test(hash_table ht)
{
return 1;
}
I want to use in hashtable.h a typedef from list.h, it's typedef struct...},*TLDI;. In the same way, list.h uses a typedef struct ...},*hash_table; from hashtable.h. Can I do something like this or I'm wrong? Cause I get this error while compiling whole project:
In file included from hashtable.h:7,
from main.c:1:
list.h:14:10: error: unknown type name ‘hash_table’
14 | int test(hash_table ht);
In file included from hashtable.h:7,
from hash_func.c:1:
list.h:14:10: error: unknown type name ‘hash_table’
14 | int test(hash_table ht);
I'm not strong in typedef and headers, but if I would get an answer to this question or at least a source from where I could find out more about them I would be very grateful.
Two headers that rely to each other are not a show stopper if well-formed. What I observe is that your include guards don't enclose the full header but only part of it, this I think is wrong. The right way to use include guards is shown in this
example header some_component.h:
#ifndef SOME_COMPONENT_H
#define SOME_COMPONENT_H
// include whatever you need here (*after* the opening guard):
#include "some_other_component.h"
// start type definitions and declarations *after* includes:
struct some_component_t {
// ...
};
#endif
This way, you headers will work most consistently:
either read completely
or completely ignored
I advise you to avoid placing definitions before includes, as this allows you to modify the content of the included content. What looks like a tempting idea at first, turns into a confusing nightmare in the long run in the vast majority of cases.
Another point is that if the definitions in the two headers really rely on each other, you should rethink your design.
Also, it's not clear why void test2(cmp_function cmp); which relies on cmp_function is declared in hashtable.h and why int test(hash_table ht); which relies on hash_table is declared in list.h; to me this seems like you were mixing up things here. In other words, by switching places of some declarations, you'd get rid of most of the entanglement.
You should also know that typedefs and pointers are allowed on incomplete types, so it's possible to declare a pointer to a structure that is not yet defined. So, for example, the following compiles:
typedef int (*hash_function)(void*,int);
typedef int (*cmp_function)(void*,void*);
typedef struct _hasht_ hasht, *hash_table;
typedef struct _node_ TNode, *TLDI;
struct _node_ {
void *info;
struct _node_ *pre, *urm;
};
struct _hasht_{
int maxElemNumber;
hash_function hf;
TLDI* key_array;
};
... as does this (version without struct typedefs):
struct _node_ {
void *info;
struct _node_ *pre, *urm;
};
typedef int (*hash_function)(void*,int);
struct _hasht_{
int maxElemNumber;
hash_function hf;
struct _node_** key_array;
};
The overall interdependency of the headers is kind of ugly, but the errors can be corrected with some forward declarations:
hashtable.h
#ifndef _HASH_TABLE_
#define _HASH_TABLE_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _hasht_ htable, *hash_table;
typedef int (*hash_function)(void*,int);
#include "list.h"
struct _hasht_ {
int maxElemNumber;
hash_function hf;
TLDI* key_array;
};
void test2(cmp_function cmp);
#endif
list.h
#ifndef _LINKED_LIST_
#define _LINKED_LIST_
typedef struct _node_ TNode, *TLDI;
typedef int (*cmp_function)(void*,void*);
#include "hashtable.h"
struct _node_ {
void *info;
struct _node_ *pre, *urm;
};
int test(hash_table ht);
#endif
i'm trying to learn how to use pycparser and during my practice I encontured this problem.
Basically I have a C file with system header like #include <stdio.h> and #include <stdlib.h> and I want to analyze it through the pycparser ast tree.
I succeded in using the fake headers so i could parse the file but then i got this problem: the ast now contains a lot of typedef and doesn't contain the real headers, so after I print the ast in a file to have my c code back, it can't compile because the real headers are missing.
For example this file:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
//my struct
} NODE;
int main() {
//do stuff
return 0;
}
becomes this:
typedef int size_t;
typedef int __builtin_va_list;
typedef int __gnuc_va_list;
typedef int va_list;
typedef int __int8_t;
....
typedef int __uint64_t;
typedef int __int_least32_t;
typedef int __uint_least32_t;
....
typedef struct xcb_connection_t xcb_connection_t;
typedef uint32_t xcb_window_t;
typedef uint32_t xcb_visualid_t;
//a lot of typedef
typedef struct {
//my struct
} NODE;
int main() {
//do stuff
return 0;
}
Doing my research i saw that #include <stdlib.h> contains the following lines:
#include "_fake_defines.h"
#include "_fake_typedefs.h"
and those headers contain all the typedef that appear in my file.
Is there a way to print back the c code with the real headers?
i´m trying to compile 3 files in C. One is main.c, where i declare the variables, another is cuenta.h and the other is cliente.h. cuenta.h has a struct used in another struct in cliente.h, but this error appears. How can I solve this? Thanks!
cliente.h
#ifndef PACABANK_CLIENTE_H
#define PACABANK_CLIENTE_H
#include "cuenta.h"
#include "fecha.h"
typedef struct {
char *dni;
char *titular;
Tarjeta tarjeta;
}InfoCliente;
cuenta.h
#ifndef PACABANK_CUENTA_H
#define PACABANK_CUENTA_H
#include "cliente.h"
#include "fecha.h"
typedef struct
{
int numero_tarjeta;
char *iban;
Fecha caducidad;
char *nombre_titular;
int cvv;
char *tipo; //mastercard, visa, american express.....
float limite;
}Tarjeta;
The error
In file included from cuenta.h:7:0,
from cuenta.c:5:
cliente.h:14:5: error: unknown type name 'Tarjeta'
Tarjeta tarjeta;
I have a program which is processing list in c, it is working perfectly as long as I have it in one source file, when I try to separate it and compile it got this error “ delete_functions.c:15:13: error: unknown type name ‘nodetype’ ” same error goes for functionality_functions.c and insert_functions.c here is the code
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "delete_functions.h"
#include "insert_functions.h"
#include "functionality_functions.h"
int main(){
//i did not upload all the main function code because it is way to long
}
types.h
typedef char AirportCode[4];
typedef struct nodetype{
char Airport[4];
struct nodetype *next;
} nodetype;
delete_functions.h
void Delete(nodetype *list,char node[4]);
void DeleteLast(nodetype *list);
functionality_functions.h
void print(nodetype *head);
nodetype *search(nodetype *list,char item[4]);
nodetype *create();
insert_functions.h
void *InsertLast(nodetype *list,char item[4]);
void *InsertAfter(nodetype *list,char item[4],char node[4]);
According to the GCC error message, there error is in the delete_functions.c file.
Presumably, it looks like this at the beginning:
#include "delete_functions.h"
Since delete_functions.h does not itself include types.h, you need to include it first:
#include "types.h"
#include "delete_functions.h"
Alternatively, you can add include guards to your headers so, that they can safely be included multiple times, like this for types.h:
#ifndef TYPES_H
#define TYPES_H
typedef char AirportCode[4];
typedef struct nodetype{
char Airport[4];
struct nodetype *next;
} nodetype;
#endif
And for delete_functions.h:
#ifndef DELETE_FUNCTIONS_H
#define DELETE_FUNCTIONS_H
void Delete(nodetype *list,char node[4]);
void DeleteLast(nodetype *list);
#endif
The *_H include guard macros are necessary because otherwise, main.c would not compile anymore: each type in types.h can only be defined once per translation unit, and without the guards, every *.h would bring in another definition, leading to compiler errors.
I need to build a "social network" for college, but I always get unknown type name 'List' while compiling. I removed a lot of functions from my headers, but I still get the same error and I don't know why.
I've got 3 headers:
My friend's header
#ifndef FRIEND_H
#define FRIEND_H
#include "ListHeadTail.h"
typedef struct Friend{
int id;
struct Friend *nextFriend;
}Friend;
void printFriends(List *l);
void removeFriend(List *l);
void addFriend(List *l);
#endif /* FRIEND_H */
My list header:
#ifndef LISTHEADTAIL_H
#define LISTHEADTAIL_H
#include "Student.h"
typedef struct pStudent{
struct pStudent *ant;
Student *s;
struct pStudent *prox;
}pStudent;
typedef struct list{
pStudent *head;
pStudent *tail;
}List;
void startList(List *l);
void printList(List *l);
void freeList(List *l);
#endif /* LISTHEADTAIL_H */
My student's header
#ifndef STUDENT_H
#define STUDENT_H
#define MAX 51
#include "Friend.h"
#include "ListHeadTail.h"
typedef struct Student{
int id;
char name[MAX];
Friend *friends;
}Student;
Student* readStudent ();
void printStudent(Student* a);
void changeData(List *l);
#endif /* STUDENT_H */
My main:
#include <stdio.h>
#include <stdlib.h>
#include "ListHeadTail.h"
#include "Friend.h"
#include "Student.h"
int main(int argc, char** argv) {
List l;
startList(&l);
freeList(&l);
return (EXIT_SUCCESS);
}
Thanks for reading.
Here's the (first) error I get when I try to compile this set of files:
$ cc main.c
In file included from main.c:4:
In file included from ./ListHeadTail.h:4:
In file included from ./Student.h:6:
./Friend.h:11:19: error: unknown type name 'List'
void printFriends(List *l);
Look at the file names and line numbers. Note that at ListHeadTail.h line 4, you've already defined LISTHEADTAIL_H, but you haven't yet reached the actual declaration of List. You then go into Student.h, and from there into Friend.h. That includes ListHeadTail.h again -- but since LISTHEADTAIL_H is already defined, this include does nothing. So you continue through Friend.h with no declaration of List, and therefore get an error on the declarations that reference it.
As noted by #lurker in their comment, the basic issue here is circular dependency, and a simple fix is forward declaration. In this case, you could simply modify Friend.H, replacing #include "ListHeadTail.h" with typedef struct list List;.
But to me this is a bit hacky. If you shift the order of includes somewhere, the build might break again.
I think the real problem is that the declarations of the functions (printFriends, etc.) don't belong in Friend.h; they belong in ListHeadTail.h. The functions have nothing to do with the Friend type. Sure, they have "Friend" in their names, but the only type referenced in the declarations is List. So they belong in ListHeadTail.h. Same goes for the changeData function in Student.h.
In an object-oriented design (say, in Java), these functions would all probably be methods of the List class, and would be declared in that class's source file.