Nesting Structs in C - c

I'm a noob at C and need some help getting my code to...welll...do anything. I have the following put into a .h file.
typedef struct
{
int active;
int dead;
ucontext_t t;
struct node *link;
}gtthread_t;
struct node{
struct gtthread_t thread;
};
typedef struct
{
int rubic;
}gtthread_mutex_t;
This is in a .h file... a .h file where I have had to #include ucontext.h ... which I know I am also not supposed to do... but it's the only way I can access ucontext_t, I find.
So, my error here is "field thread has incomplete type".
Why? What does that even mean? And how can I possible NOT import ucontext.h if I want to declare structs with that kind of data in the .h file?

Has nothing to do with your other include. This has to do with the fact that your first struct is anonymous and has a type name gtthread_t. C unlike C++ distinguishes between gtthread_t and struct gtthread_t.
Either name the struct:
struct gtthread_t
{
int active;
int dead;
ucontext_t t;
struct node *link;
};
Or change the type name to the typedef:
struct node{
gtthread_t thread;
};

The ucontext.h header only pre-declares the ucontext_t type. You're only supposed to use pointers to it, since its size is not known. Change your code to:
ucontext_t *t;
and you will be fine. Notice that all the functions in the ucontext.h header use such pointers to refer to contexts. This is common in C API design, since it allows the representation to be hidden inside the API's implmentation, which is nice.

One problem is that struct node has not been declared yet, so the gtthread_t type cannot be completed.
typedef struct
{
int active;
int dead;
ucontext_t t;
struct node *link;
}gtthread_t;
struct node{
struct gtthread_t thread;
};
You'll need a forward declaration of struct node:
struct node;
typedef struct
{
int active;
int dead;
ucontext_t t;
struct node *link;
}gtthread_t;
struct node{
struct gtthread_t thread;
};
Try that and see if it makes a difference.

Related

What does the variable after the bracket do in a struct

I'm a little confused about the structure of this struct. What is the point of typedef if you can name the struct to whatever you want without it? Is it also necessary to have " struct" in struct data_el *next when you are creating the next pointer; and wouldn't be confusing to also name that pointer the same name as the struct itself? Also, what is the point of having data_el after the bracket, when you can create a new struct in the program whenever you want, without naming an instance of it?
typedef struct data_el_{
int data;
struct data_el_ *next;
}data_el;
You can use struct like this:
struct data_el_ {
int data;
struct data_el_ *next;
};
struct data_el_ my_data_el;
But you can also typedef a struct:
typedef struct data_el_ {
int data;
struct data_el_ *next;
} data_el;
data_el my_data_el;
In the latter case, you can still use struct data_el_. However, inside the struct itself you must use struct data_el_.
For more information, check out the following related questions:
typedef struct vs struct definitions
Why should we typedef a struct so often in C?

Pointer in typedef struct confusion

I am trying to define a typedef struct as follows:
typedef struct node{
int keys[2*MIN_DEGREE-1];
struct node* child[2*MIN_DEGREE];
int numkeys;
int isleaf;
} BNODE,*BNODEPTR;
Instead of using struct node* child[2*MIN_DEGREE] why can't I declare the struct as follows:
typedef struct node{
int keys[2*MIN_DEGREE-1];
BNODEPTR child[2*MIN_DEGREE];
int numkeys;
int isleaf;
} BNODE,*BNODEPTR;
I am little confused as to how the compiler resolves structs that has nested pointers to the same type. It will be great somebody helps me clear this up.
Thanks
You can't use BNODEPTR in the body of the structure like that because it either doesn't exist as a type at all until after the definition after the close brace of the structure body, or (worse) it refers to a different type altogether*.
You could use:
typedef struct node BNODE, *BNODEPTR;
struct node
{
int keys[2*MIN_DEGREE-1];
BNODEPTR child[2*MIN_DEGREE];
int numkeys;
int isleaf;
};
And there's another whole argument that says BNODEPTR is evil and you should only use BNODE and BNODE *, but that's a style issue, not a technical one.
Were it my code, it would probably be more like:
typedef struct Node Node;
struct Node
{
int keys[2*MIN_DEGREE-1];
Node *child[2*MIN_DEGREE];
int numkeys;
int isleaf;
};
In C++, the rules are slightly different and you would not need the typedef line (so Node would be known as a type from the open brace).
* This can only happen if the original BNODEPTR is defined at an outer scope and this one appears inside a function, but when it happens, it is really confusing!
Instead of using struct node* child[2*MIN_DEGREE] why can't I declare
the struct as follows: BNODEPTR child[2*MIN_DEGREE];?
At that point, compiler (yet) does not know what the symbol BNODEPTR is.

Pointer typecasting in c

I am writing an implementation of graphs in C language. I came across a situation where I am not able to figure out the reason for the way the compiler is behaving with a pointer typecast warning.
Here are the structures;
#define MAXV 10
typedef struct {
int y;
int weight;
struct edgenode *next;
} edgenode;
typedef struct {
edgenode *edge[MAXV+1];
int degree[MAXV+1];
// other info of graph
} graph;
// operation in some other function
p->next = g->edge[x];
I got a pointer typecast warning[enabled by default] when I do this kind of operation.
I was not able to remove this warning even after trying to typecast with every possible cast.
Finally I made a code change in the structure and suddenly the warning was gone.
The structure code change was this:-
typedef struct edgenode { // note that I have added structure name here
// same as above definition
} edgenode;
// operation in some other function
p->next = g->edge[x];
Now the warning is gone and code runs without any warnings.
I do not understand why is this happening; can anybody help me with this problem?
The problem is here:
typedef struct {
int y;
int weight;
struct edgenode *next;
} edgenode;
It is not clear what type struct edgenode *next; is referring to (it doesn't matter; somewhere, presumably, there's a struct edgenode defined), but it is not this structure because it has no tag. You need:
typedef struct edgenode
{
int y;
int weight;
struct edgenode *next;
} edgenode;
Now the pointer refers to another structure of this same type. So, the fix you found was the correct fix for your problem.
Remember: a typedef is an alias (alternative name) for an existing type. You created a type name edgenode, but you had not defined the type struct edgenode. You don't have to fully define a structure type before you create pointers to it; this can be a good way of creating 'opaque types'.
The other way to define things is:
typedef struct edgenode edgenode;
struct edgenode
{
int y;
int weight;
edgenode *next;
};
This says that the type name edgenode is an alias for a struct edgenode; the structure definition then tells the compiler what a struct edgenode looks like.

initialize struct in c

typedef struct Node{
int x;
int y;
struct Node* next;
}Node;
i want create in main "list" in this way:
int main(){
Node list;
}
and not in this way:
int main(){
Node list = {1,2,NULL};
}
i want initialize a struct in declaration of struct
tryed this way:
typedef struct Node{
int x;
int y;
struct Node* next;
}Node = {1,2,NULL};
error C2513: 'Node' : no variable declared before '='
need help
You can't give structure members predefined values in C. Use a constructor-like function or a constructor-like macro.
The typedef (or struct) "statement" defines a type, not an object.
Types have no value. It only makes sense to speak of values in relation to objects.
Objects do not have a default value (other than 0 when they're implicitly initialized).
So you can't do what you want.

C question: error: expected ')' before '*' token

Edit 2
Thanks for all the suggestions, I edited the code below from the suggestions given. However, it still doesnt seem to compile. But nevertheless, thanks a lot for the help hands.
Edit
I apologize for not putting the pcb struct into the code snippet. There is a struct called pcb defined in above the two structs I originally posted. Namely,
typedef struct pcb{
UINT32 proc;
struct pcb *link;
}pcb;
Hi,
I asked a question regarding structs in C a few minutes ago and got an answer blazing fast. But now I'm facing another problem, namely the error in the title of this question. I'm trying to implement a simple priority queue in C using arrays of queues. However, when I try to declare a function on pcb_pQ structure, I get the above error. I have the structs clearly defined in the heard file.
In the header file:
typedef struct pcb_Q{
pcb *head;
pcb *tail;
SINT32 size;
} pcb_Q;
typedef struct pcb_pQ {
pcb_Q queues[5];
SINT32 size;
} pcb_pQ;
Function prototype in header file:
/*priority queue operations*/
VOID pcb_pq_enqueue(pcb_pQ*, pcb*);
Function impelmentation in .c file:
VOID pcb_pq_enqueue(pcb_pQ* pcb_pQ_p, pcb* pcb_p) {
pcb_Q* pcb_Q_p;
int priority;
priority = pcb->proc_priority;
pcb_Q_p = &pcb_pQ->queues[priority];
pcb_enqueue(pcb_Q_p, pcb);
}
When I try to compile the above code, I get an "error: expected ')' before '*' token". This error is pointing to the function signature in the .c file, namely
VOID pcb_pq_enqueue(pcb_pQ* pcb_pQ_p, pcb* pcb_p) {
But I am not sure why I am getting this error, could someone give me a hand? Thanks a lot.
Are you including the header file? Barring misspellings, that error is almost invariably caused by a missing typedef.
In other words, the compiler doesn't know about either the pcb_pQ or pcb type (or both).
Edit: There's something else wrong because this compiles fine:
qq.h
typedef struct pcb {
unsigned int proc;
struct pcb *link;
} pcb;
typedef struct{
pcb *head;
pcb *tail;
int size;
} pcb_Q;
typedef struct pcb_pQ {
pcb_Q queues[5];
int size;
} pcb_pQ;
void pcb_pq_enqueue(pcb_pQ*, pcb*);
qq.c:
#include <stdio.h>
#include "qq.h"
void pcb_pq_enqueue(pcb_pQ *pcb_pQ, pcb *pcb) {}
int main (void) { return 0; }
I had to use other types (and I modified the pcb structure to be a named one - I'm not sure your given one should have compiled since as-is since there is no struct pcb type in existence).
Based on all the comments and answers to date, I'm pretty certain there's something wrong with your compiler. GCC compiles that snippet above just fine.
Try putting my two files above onto your system and seeing if they compile okay.
And be aware that you do need to name your pcb structure. See here for the gory details but the consensus seems to be that
typedef struct {
unsigned int proc;
struct pcb *link;
} pcb;
will define a struct pcb incomplete type which is a distinct type from pcb (and the structure you're currently defining).
It looks like the compiler doesn't find the defintion of pcb.
Change:
typedef struct{
UINT32 proc;
struct pcb *link;
}pcb;
to:
typedef struct pcb {
UINT32 proc;
struct pcb *link;
} pcb;
First, it is 'void' not 'VOID' until or unless you have definition like
#define VOID void
This can be better if
typedef struct tag_struct_pcb_Q {
pcb *head;
pcb *tail;
SINT32 size;
} pcb_Q;
typedef struct tag_structpcb_pQ {
pcb_Q queues[5];
SINT32 size;
} pcb_pQ;
modern 'C' compiler expect the return type must be mentioned.
If you have definition like this also cause error.
#define VOID
Another possibility
VOID pcb_pq_enqueue(pcb_pQ* pcb_pQ, pcb* pcb) {
where does pcb is from? it is not good to have pcb* pcb. ALWAYS give different name for variable type and variable name

Resources