Error when I try to declare bag struct? - c

bag-implementation.h:
typedef struct node {
struct node *next;
char *element;
int repeats;
} Node;
typedef struct{
size_t size;
Node *head;
}Bag;
Line that errors in bag.c (which includes bag.h which includes bag-implementation.h):
Bag bag_union(Bag bag1, Bag bag2){
Bag union;
return bag1;
}
Error:
bag.c: In function 'bag_union':
bag.c:188:12: error: expected '{' before ';' token
bag.c:188:7: error: two or more data types in declaration specifiers
make: *** [bag.o] Error 1
If I try to compile without creating that bag, then it works fine. What is the issue?

union is a reserved word in C, so you can't have a variable called like this. Simply rename it.

union is a keyword it can't be used for variable.
This is the rule to define a variable.

Related

expected declaration specifiers or '...' before 'record_t' in header files c

I'm new to this header files in C.
What I'm trying to do is using makefile to compile my code files together. I have 2 header files and 2 c files for each header, also 1 main.c file.
I have main.c which is my main function and it has "#include "dict2.h"". dict1 and dict2 headers are somewhat the same. the difference is dict2 has additional linked list function.
-bash-4.1$ make dict1
gcc -Wall -c main.c -o main.o -g
In file included from main.c:6:
dict2.h:1: warning: useless storage class specifier in empty declaration
dict2.h:8: warning: useless storage class specifier in empty declaration
dict2.h:21: error: expected declaration specifiers or '...' before 'record_t'
dict2.h:24: error: expected declaration specifiers or '...' before 'record_t'
dict2.h:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
dict2.h:45: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
dict2.h:48: error: expected ')' before '*' token
make: *** [main.o] Error 1
my dict2.h funtion is looking like this:
typedef struct record_t;
typedef struct node_list node_list_t;
struct node_list;
typedef struct list_t;
typedef struct node node_t;
struct node;
node_t* transform_input(FILE *finput, node_t *root);
//line 21
node_t* bst_insert(node_t *root, record_t* data);
//line 24
node_t* bst_create_node(node_t* root, record_t* data);
node_t* bst_search(node_t* root, char* name_keyword, int* numcomparison);
void search_then_print(char* keyword, node_t* root, FILE* foutput, \
int* numcomparison);
void freeTree(node_t *root);
void print_record(FILE* foutput, node_t* targetnode, char* keyword,\
int* numcomparison);
//line 42
list_t *insert_at_foot(list_t *list, record_t *datarecord);
//line 45
list_t *create_empty_list(void);
//line 48
void free_list(list_t* list);
I've looked at the discussion online but and trying to fix it but I couldn't find the errors in the header file.
Thank you for your help.
Statements:
typedef struct record_t;
typedef struct list_t;
miss the typenames.
Should probably be:
typedef struct record record_t;
typedef struct list list_t;
In the following, I use struct tag vs. type identifier. I googled a bit and found a (IMHO) quite easy to understand explanation on Wikipedia.
Some programmer dude mentioned this but it seems you didn't understand his point. So, I elaborate this a little bit:
This is valid:
struct Node {
struct Node *pNext;
};
and can be used with struct:
void insert_after(struct Node *pNode);
For whom which are to lazy to type the struct always a typedef can help:
struct Node {
struct Node *pNext;
};
typedef struct Node Node;
It might look confusing but the compiler separates struct tags and types in separate lists. Thus, the first and second Node is no identifier "collision".
Both can be done in at once:
typedef struct Node {
struct Node *pNext;
} Node;
Assuming another case without "recursive" usage of type, the struct tag can even be left out:
typedef struct {
int year, month, day;
} Date;
This is a struct type which can be used exclusively without struct keyword.
I assume this was intended when writing
typedef struct record_t;
but the compiler interpretes it not as the writer might intend it. The compiler reads this as struct with tag record_t and a missing type identifier.
This is how I read the
warning: useless storage class specifier in empty declaration
(It helps to know that typedef is syntactically handled in the compiler like static and extern and, thus, counted as storage class though this seems not quite obviously to everybody.)
I must admit that I don't know how to interprete the
error: expected declaration specifiers or '...' before 'record_t'
but I would ignore this and just fix the weakness in the typedef (and count the error as follow-up error.)
I also must admit that I have no idea how to solve this with an anonymous struct and go with the idea of a struct with a tag which is "re-used" as type identifier:
#include <stdio.h>
/* typedef for an incomplete struct */
typedef struct Date Date;
/* use incomplete struct type for prototype of function */
void printDate(Date *pDate);
/* define the complete struct */
typedef struct Date {
int year, month, day;
} Date;
/* implementation of function */
void printDate(Date *pDate)
{
printf("%04d/%02d/%02d", pDate->year, pDate->month, pDate->day);
}
/* check this out */
int main(void)
{
Date date = { 2018, 9, 3 };
printDate(&date);
return 0;
}
Output:
2018/09/03
Live Demo on ideone

Creating a simple Binary Search Tree

I've been trying to create a binary search tree that sorts in alphabetical order according to their "company" name out of these structs with recursion for quite a while now. The movement through the structs to get the pointers to point to the right spots is confusing me a lot.
I'm getting these errors:
gcc -c tree.c
tree.c: In function ‘treeInsert’:
tree.c:34:11: error: request for member ‘entryPtr’ in something not a structure or union
tree.c:36:55: error: request for member ‘entryPtr’ in something not a structure or union
tree.c:38:12: error: request for member ‘right’ in something not a structure or union
tree.c:39:35: error: request for member ‘right’ in something not a structure or union
tree.c:43:12: error: request for member ‘left’ in something not a structure or union
tree.c:44:35: error: request for member ‘left’ in something not a structure or union
tree.c:47:3: warning: passing argument 1 of ‘printTree’ from incompatible pointer type [enabled by default]
In file included from tree.c:19:0:
tree.h:36:6: note: expected ‘struct treeNode *’ but argument is of type ‘struct treeNode ’
make: * [tree.o] Error 1
Here are the structs:
typedef struct companyEntryTag{
char * companyName;
char * companyDescription;
char * website;
char * streetAddr;
char * suiteNumber;
char * city;
char * state;
int zip;
double latitude;
double longitude;
} companyEntry;
typedef struct treeNodeTag{
companyEntry * entryPtr;
struct treeNodeTag * left;
struct treeNodeTag * right;
} treeNode;
typedef struct listNodeTag{
companyEntry * entryPtr;
struct listNodeTag * next;
} listNode;
I've tried a bunch of different solutions, but here is my current function I'm using to try to do this, that got the above error:
int treeInsert(listNode * list, treeNode ** rootPtr)
{
if(list == NULL){return -1;}
//Make the root next point to what list is
*rootPtr->entryPtr = list->entryPtr;
if(strcmp(list->next->entryPtr->companyName, rootPtr->entryPtr->companyName)==1)
{
rootPtr->right->entryPtr = list->next;
treeInsert(list->next, rootPtr->right->entryPtr);
}
else
{
rootPtr->left->entryPtr = list->next;
treeInsert(list->next, rootPtr->left->entryPtr);
}
printTree(rootPtr);
return 0;
}
I'm not perfectly sure of what the errors are telling me now that I have tried all these different ways of implementing the function. I'm all jumbled up and would love some help!
It should be (*rootPtr)->entryPtr, not *rootPtr->entryPtr or rootPtr->entryPtr.
Due to operator precedence, *rootPtr->entryPtr is indeed *(rootPtr->entryPtr).

C requires that a struct or union has at least one member

I'm getting a bunch of weird errors from the compiler when I try to compile this code.
I'm just trying to write a basic linked list, and the header file compiles fine when run on its own but when I compile the c file everything falls apart
linkedlist.h
typedef struct Data
{
char *title;
} Data;
typedef struct LinkedList
{
LinkedList *next;
Data *data;
} LinkedList;
LinkedList *createnew(void);
void destroylist(LinkedList *old);
Data *adddata(void);
void destroydata(Data *old);
LinkedList.c
#include <stdlib.h>
#include "linkedlist.h"
LinkedList *createnew(void) {
LinkedList *newnode = (LinkedList *) malloc(sizeof(LinkedList));
newnode->data = adddata();
newnode->next = NULL;
return newnode;
}
void destroylist(LinkedList *old) {
destroydata(old->data);
free(old);
return;
}
Data *adddata(void) {
Data *newdata = (Data *) malloc(sizeof(Data));
newdata->title = NULL;
return newdata;
}
void destroydata(Data *old) {
free(old->title);
free(old);
return;
}
and finally what the compiler spits out
linkedlist.h(8): error C2016: C requires that a struct or union has at least one member
linkedlist.h(8): error C2061: syntax error : identifier 'LinkedList'
linkedlist.h(10): error C2059: syntax error : '}'
linkedlist.h(12): error C2143: syntax error : missing '{' before '*'
linkedlist.h(13): error C2143: syntax error : missing ')' before '*'
linkedlist.h(13): error C2143: syntax error : missing '{' before '*'
linkedlist.h(13): error C2059: syntax error : ')'
linkedlist.c(4): error C2143: syntax error : missing '{' before '*'
linkedlist.c(5): error C2065: 'LinkedList' : undeclared identifier
linkedlist.c(5): error C2065: 'newnode' : undeclared identifier
linkedlist.c(5): error C2059: syntax error : ')'
linkedlist.c(6): error C2065: 'newnode' : undeclared identifier
linkedlist.c(6): error C2223: left of '->data' must point to struct/union
linkedlist.c(7): error C2065: 'newnode' : undeclared identifier
linkedlist.c(7): error C2223: left of '->next' must point to struct/union
linkedlist.c(8): error C2065: 'newnode' : undeclared identifier
linkedlist.c(8): warning C4047: 'return' : 'int *' differs in levels of indirection from 'int'
linkedlist.c(11): error C2143: syntax error : missing ')' before '*'
linkedlist.c(11): error C2143: syntax error : missing '{' before '*'
linkedlist.c(11): error C2059: syntax error : ')'
linkedlist.c(11): error C2054: expected '(' to follow 'old'
I'm confused because it looks like it finds both files but then it has trouble with the header even though it works fine alone.
Any help would be great.
Thanks
The error message is strange, but
typedef struct LinkedList
{
LinkedList *next;
Data *data;
} LinkedList;
LinkedList is not a known type in the definition, it is only known after the definition is complete, it must be
typedef struct LinkedList
{
struct LinkedList *next;
Data *data;
} LinkedList;
Header files aren't compiled on their own. Their only use is being #included elsewhere.
The error in your header is this part:
typedef struct LinkedList // <- defines the type 'struct LinkedList'
{
LinkedList *next; // <- attempts to use the type 'LinkedList', which isn't defined at this point
} LinkedList; // <- defines the type 'LinkedList', or it would if the previous code were correct
There are a few possible ways to fix this:
// forget about 'LinkedList'; just use 'struct LinkedList' everywhere
struct LinkedList {
struct LinkedList *next;
};
// use 'struct LinkedList' in its own definition but provide typedef to users
struct LinkedList {
struct LinkedList *next;
};
typedef struct LinkedList LinkedList;
// like the previous version, but combine struct + typedef
typedef struct LinkedList {
struct LinkedList *next;
} LinkedList;
And my favorite:
// establish alias first, then use it everywhere
typedef struct LinkedList LinkedList;
struct LinkedList {
LinkedList *next;
};
Try this, which is cleaner than alternate suggestions (edit: I see that melpomene mentioned this before me):
typedef struct Data Data;
struct Data
{
char *title;
};
typedef struct LinkedList LinkedList;
struct LinkedList
{
LinkedList *next;
Data *data;
};
You will find if/when you move on to C++ that you can just remove the typedef lines.
If you have mutually referring structs, move all the typedefs up to the top, e.g.,
typedef Type1 Type1;
typedef Type2 Type2;
struct Type1
{
Type2* link;
};
struct Type2
{
Type1* link;
};
Besides adding struct before LinkedList, you might need to explicitly set the "compile as" option to c++ in Visual Studio.
I had struggled with this C2016 error for a while and it finally been fixed by setting the option.

Attempting to define two dependable structures in C

I am trying to define two structures in C when the second struct uses the first as an array member and has two pointer members of itself.
Visual Studio does not like my code:
syntax error : '}'
syntax error : identifier 'tokenListNode'
syntax error : missing '{' before '*'
any idea how to solve this?
--> Please note that the errors appear with or without the declarations I added at the beginning of the code.
--> In addition, if someone can explain to me what is the difference between the identifier
before and after the struct's curly brackets, I'll be grateful.
Below is the code:
#define ARRAY_SIZE 100
struct tokenListNode;
struct TOKEN_LIST_NODE;
enum TOKEN_TYPE
{
id = 0,
INT_NUM,
INT_REAL,
ASSIGNMENT_OP,
RELATION_OP,
ARITHMETIC_OP
} tokenType;
typedef struct TOKEN
{
char* lexema;
enum TOKEN_TYPE type;
int lineNumber;
} token;
typedef struct TOKEN_LIST_NODE
{
token tokenArray[ARRAY_SIZE];
tokenListNode* prevNode;
tokenListNode* nextNode;
int tokenCounter;
}tokenListNode;
You do not define tokenListNode until after you use it. Change to the following:
typedef struct TOKEN_LIST_NODE tokenListNode;
struct TOKEN_LIST_NODE
{
token tokenArray[ARRAY_SIZE];
tokenListNode* prevNode;
tokenListNode* nextNode;
int tokenCounter;
};
The definition of a structure is composed of the keyword struct; the "struct tag"; and the struct members
struct tag { int member1; /* &c */ };
You can leave the tag out and create an unnamed structure ... why you would do so is another matter: you can't refer to the structure without a struct tag!
struct { int member1; /* &c */ };
Also, you can take any type and give it another name using typedef
typedef old_type new_name;
as in
typedef struct tag { int member1; /* &c */ } tag;
/* <------------ old type ------------> <new name> */
The above line defines a struct (named struct tag) and, at the same time, gives that type a new name: tag
what is the difference between the identifier before and after the struct's curly brackets
That's the result of mixing definition of struct and typedef. The name before the {} is the "tag" of the structure, the name after the {} is the new name for the type being typedef'd.
You need to use the struct tag instead of it's typedef'ed version when referring to itself.
struct TOKEN_LIST_NODE
{
token tokenArray[ARRAY_SIZE];
struct TOKEN_LIST_NODE* prevNode;
struct TOKEN_LIST_NODE* nextNode;
int tokenCounter;
};

recurrent declare in c

typedef void (callback)(int *p1, sStruct *p2);
typedef struct _sStruct
{
callback *funct;
}sStruct;
I have the following declaration, in C. How can I compile this recurrent declaration without receiving any error ?
For the moment I receive: syntax error before '*' token on first line.
You can forward-declare the structure:
/* Tell the compiler that there will be a struct called _sStruct */
struct _sStruct;
/* Use the full name "struct _sStruct" instead of the typedef'ed name
"sStruct", since the typedef hasn't occurred yet */
typedef void (callback)(int *p1, struct _sStruct *p2);
/* Now actually define and typedef the structure */
typedef struct _sStruct
{
callback *funct;
} sStruct;
Edit: Updated to match the question's change of type names.
Also, I strongly suggest that you do not give the struct the identifier _sStruct. Global names beginning with a _ are reserved names, and using them for your own identifiers could cause undefined behavior.

Resources