I'm trying to create an structure with other structures inside.
struct bullet{
char bullet_sprite[100];
int pos_x;
int pos_y;
int ace_x;
int tag;
};
struct bullets_onscreen{
struct bullet v[2];
struct bullet a[2];
};
I get this error:
error: array type has incomplete element type
Is this posible to do?
Example code:
//Calling functions
struct bullets_onscreen[2] //public
struct bullet bala[1];
init_bullet(&bala,_player);
set_bullet_on_screen(&bala);
void set_bullet_on_screen(struct bullet *_bullet){
array_bullet[1] = _bullet;
}
void init_bullet(struct bullet *_bullet, struct player *_player){
//inits all bullet components
}
As written your code is fine. Presumably in the actual code you have reversed the order of the two struct definitions. This code produces the error you report:
struct bullets_onscreen{
struct bullet v[2];
struct bullet a[2];
};
struct bullet{
char bullet_sprite[100];
int pos_x;
int pos_y;
int ace_x;
int tag;
};
Define the structs in the order that you did in the question and your code will compile.
Related
How do I make this struct instruction visible to struct cpu state? Like If I put cpu state struct first it doesn't work because some other arguments won't be visible to struct instruction but if I put it reverse again I have a problem.
struct cpu_state
{
int nextinstructionlinenumber;
char filename[200];
char RLO;
struct instruction instructionlist[INSTRUCTIONLIST_SIZE];
int instructionlistnumber;
struct variable variablelist[INSTRUCTIONLIST_SIZE];
int variablelistnumber;
};
struct cpu_state CPU;
struct instruction{
char name[LINE_CHAR_NUM];
void(*function)(struct cpu_state* pstate, struct line* pline);
};
You can create incomplete structure declarations provided they are just used for pointers. For example, the following order will work. Note that I created a dummy definition for struct variable since it was absent from the post. You can replace it with whatever you like:
struct variable {
int dummy_val;
};
struct cpu_state;
struct line;
struct instruction{
char name[LINE_CHAR_NUM];
void(*function)(struct cpu_state* pstate, struct line* pline);
};
struct cpu_state
{
int nextinstructionlinenumber;
char filename[200];
char RLO;
struct instruction instructionlist[INSTRUCTIONLIST_SIZE];
int instructionlistnumber;
struct variable variablelist[INSTRUCTIONLIST_SIZE];
int variablelistnumber;
};
struct cpu_state CPU;
I have two seperat files
in main function file 1:
struct entity{
unsigned int pos_x;
unsigned int pos_y;
unsigned int health;
} player;
struct inventory{
char helmet[length_item_names];
char body[length_item_names];
char legs[length_item_names];
char items[inventory_space];
} items;
render_screen(rendered_size_x, inventory_size_x, screen_size_y, map, player, items);
file 2:
void render_screen(int render_size_x, int inventory_size_x, int screen_size_y, char **field, struct entity player, struct inventory items){
...
}
when declaring render_screen i either get a error telling me that the struct entity and struct inventory can't be declared as incomplete data types or when i do
extern struct Player{
...
}
it tells me that the data type i give as a parameter is wrong
how can i give the struct as a prameter
The comment of Barmar workerd.
I had to put the declaration of the struct into a header file that i had to include in both c files.
Thanks for the quick help
I was looking at this example and I found out that there is the declaration
struct edge
{
int x;
int y;
int weight;
struct edge *link;
}*front = NULL;
What does this actually mean? Is it possible to create a structure which is also a pointer with the name front and it NULL...?
A struct is just another C type, as such, the variables it is used to define, may be created as normal instances, or pointers:
int a, *pA=NULL; //normal instance, pointer instance
struct edge
{
int x;
int y;
int weight;
struct edge *link;
}sEdge, *front = NULL; //normal instance, pointer instance
And, as with any pointer variable, needs to be pointed to owned memory before it can be safely used: (examples)
int main(void)
{
// both variable types are handled the same way...
pA = &a; //point pointer variable to normal instance of `int a`
front = &sEdge;//point pointer `front` to instance of 'struct edge'
//allocate memory, resulting in assigned address with associated memory.
pA = malloc(sizeof(*pA));
front = malloc(sizeof(*front));
...
EDIT to answer question in comments:
This small example throws no error or warning. (Edit your question above, or better yet, post another question showing details of what you are seeing.)
struct edge
{
int x;
int y;
int weight;
struct edge *link;
}*front = '\0';
int main(void)
{
struct edge tree[10];
return 0;
}
It is a pointer to a struct and a declaration of a new type called struct edge.
Maybe that would put some more light, when you write:
struct edge
{
int x;
int y;
int weight;
struct edge *link;
};
You are saying: I'm creatig struct edge, which I will use to define objects of this struct by typing:
struct edge edgeObject;
But when you write:
struct edge
{
int x;
int y;
int weight;
struct edge *link;
} edgeObject;
You are saying: I'm creating struct edge and at the same time I'm defining edgeObject which is of type struct edge.
And this allows you to use that object directly as it is already defined:
edgeObject.x = 0;
So going back to your example you are saying: I'm creating structure edge and at the same I'm defining pointer to that struct front which is set to NULL.
Can anyone explain me what is the difference between this:
typedef struct{
char a[10];
int b;
char c[8];
...
}test;
and this:
typedef struct test{
char a[10];
int b;
char c[8];
...
}test;
Thanks
typedef struct{
char a[10];
int b;
char c[8];
...
}test;
The above defines an anonymous struct and immediately typedefs it to the type alias test.
typedef struct test{
char a[10];
int b;
char c[8];
...
}test;
This however, creates a struct named struct test as well as adding a typedef for it.
In the first case, you will not be able to forward declare the struct if you need to.
There's also a philosophy (which I happen to agree with to a point), that typedefing all structures by default makes code less readable, and should be avoided.
Having "test" in two different places is a bit confusing. I usually write code like this:
typedef struct test_s {
...
} test;
Now I can either use type struct test_s or just test. While test alone is usually enough (and you don't need test_s in this case), you can't forward-declare pointer to it:
// test *pointer; // this won't work
struct test_s *pointer; // works fine
typedef struct test_s {
...
} test;
With the first version you can only declare:
test t;
With the second versijon you can choose between:
struct test t;
test t;
Short answer: They're the same (in your code)
Long answer: Why put test between typedef struct and {? Is that pointless?
This (struct name test) is pointless in your code
In this code however, it's not:
struct Node {
int data;
struct Node * next;
} head;
What is the best way to resolve the following circular dependency in typedef-ing these structs?
Note the C language tag - I'm looking for a solution in standard gcc C.
typedef struct {
char* name;
int age;
int lefthanded;
People* friends;
} Person;
typedef struct {
int count;
int max;
Person* data;
} People;
The answer lies in the difference between declaration and definition. You are attempting to declare and define in the same step (in the case of a new type via typedef). You need to break these up into different steps so the compiler knows what you are talking about in advance.
typedef struct Person Person;
typedef struct People People;
struct Person {
char* name;
int age;
int lefthanded;
People* friends;
};
struct People {
int count;
int max;
Person* data;
};
Note the addition of the two 'empty' typedefs at the top (declarations). This tells the compiler that the new type Person is of type 'struct Person' so that when it sees that inside the definition of struct People it knows what it means.
In your particular case, you could actually get away with only predeclaring the People typdef because that is the only type used before it is defined. By the time you get into the definition of struct People, you have already fully defined the type Person. So the following would also work but is NOT RECOMMENDED because it is fragile:
typedef struct People People;
typedef struct {
char* name;
int age;
int lefthanded;
People* friends;
} Person;
struct People {
int count;
int max;
Person* data;
};
If you swap the order of the structure definitions (moving struct People above the typedef of Person) it will fail again. That's what makes this fragile and, therefore, not recommended.
Note that this trick does NOT work if you include a struct of the specified type rather than a pointer to it. So, for example, the following WILL NOT compile:
typedef struct Bar Bar;
struct Foo
{
Bar bar;
};
struct Bar
{
int i;
};
The above code gives a compiler error because the type Bar is incomplete when it tries to use it inside the definition of struct Foo. In other words, it doesn't know how much space to allocate to structure member 'bar' because it hasn't seen the definition of struct bar at that point.
This code will compile:
typedef struct Foo Foo;
typedef struct Bar Bar;
typedef struct FooBar FooBar;
struct Foo
{
Bar *bar;
};
struct Bar
{
Foo *foo;
};
struct FooBar
{
Foo foo;
Bar bar;
FooBar *foobar;
};
This works, even with the circular pointers inside Foo and Bar, because the types 'Foo' and 'Bar' have been pre-declared (but not yet defined) so the compiler can build a pointer to them.
By the time we get to defining FooBar, we have defined how big both Foo and Bar are so we can include the actual objects there. We can also include a self-referential pointer to type FooBar because we have pre-declared the type.
Note that if you moved the definition of struct FooBar above the definitions of either struct Foo or Bar, it would not compile for the same reason as the previous example (incomplete type).
Forward-declare one of the structs:
struct people;
typedef struct {
/* same as before */
struct people* friends;
} Person;
typedef struct people {
/* same as before */
} People;
As for readability :
typedef struct Foo_ Foo;
typedef struct Bar_ Bar;
struct Foo_ {
Bar *bar;
};
struct Bar_ {
Foo *foo;
};
It might be a good idea to avoid typedef struct altogether;
Since Person just wants a pointer to People, it should be fine to just predeclare the latter:
typedef struct People People;
Then change the second declaration to just declare using the struct tag, like so:
struct People {
int count;
int max;
Person data[];
};
struct _People;
typedef struct {
char* name;
int age;
int lefthanded;
struct _People* friends;
} Person;
struct _People {
int count;
int max;
Person data[1];
};
Note: Is Person data[]; standard?
struct People_struct;
typedef struct {
char* name;
int age;
int lefthanded;
struct People_struct* friends;
} Person;
typedef struct People_struct {
int count;
int max;
Person data[];
} People;