Error initializing stuct in source code - c

I am using some code made by someone else, to implement a kalman filter into my imu with arduino. I understand the vast majority of it and the maths behind it, but i am having some errors when implementing it which i cannot understand (serious lack of knowledge on typdefs and structs and initializing them). If someone could explain this error to me it would be much appreciated.
The header file contains this...
struct kalman_data{
float x1, x2, x3;
float p11, p12, p13,
p21, p22, p23,
p31, p32, p33;
float q1, q2, q3;
};
typedef struct _kalman_data kalman_data;
void kalman_data(kalman_data* data);
void kalman_calc(kalman_data* data, float z1, float z2);
My arduino code contains this..
kalman_data pitch_data;
kalman_data roll_data;
void loop(){
kalman_data(&pitch_data);
kalman_data(&roll_data);
kalman_calc(&pitch_data, pitch, gyro_yz);
kalman_calc(&roll_data, roll, gyro_xz);
}
And this is the error i get...
In file included from test.ino:2:0:
E:\Users\Alexander\Documents\Arduino\libraries\Kalman/kalman.h:30:29: error: conflicting declaration 'typedef struct _kalman_data kalman_data'
typedef struct _kalman_data kalman_data;
E:\Users\Alexander\Documents\Arduino\libraries\Kalman/kalman.h:17:8: error: 'struct kalman_data' has a previous declaration as 'struct kalman_data'
struct kalman_data{

struct kalman_data{
should be
struct _kalman_data{
in order to correspond to the subsequent
typedef struct _kalman_data kalman_data;
Then, the function
void kalman_data(kalman_data* data);
should better be renamed. As I recall both C and C++ allow you to reuse a type name for a function, to have both in scope at the same time, but even if that's allowed it's absolutely not a good idea. Very confusing.

The struct definition is reserving the name kalman_data and the typedef is trying to reserve the name again, for a struct called _kalman_data. This causes the error.
To rectify this, use struct _kalman_data and then the typedef will work as intended.

Related

Correct names, but "dereferencing pointer to incomplete type"

I'm stuck with this error:
cities.c: In function ‘main’:
cities.c:7:48: error: dereferencing pointer to incomplete type ‘struct Graph’
printf("well, it got here. nodeCount: %d\n", x->nodeCount);
All other solutions point out that names are misspelled and thus undefined, however, if I move the struct Graph definition to the header, it works just fine.
I had previously used this mechanic in my other library and it still compiles just fine, I've spent hours trying to move things around to no avail.
graph.h:
#ifndef GRAPH_H
#define GRAPH_H
typedef struct Graph * Graph;
int graphCreate(Graph*, int);
int graphAddPath(Graph, int, int, unsigned int);
int graphRemovePath(Graph, int, int);
int graphDestroy(Graph*);
#endif /* GRAPH_H */
graph.c: https://pastebin.com/FzkaJJwP
cities.c:
#include "graph.h"
#include <stdio.h>
int main() {
Graph x;
graphCreate(&x, 5);
printf("well, it got here. nodeCount: %d\n", x->nodeCount);
}
Output is as expected in my library at https://git.mif.vu.lt/emiliskiskis/c_deck.
Thank you for you help.
The definition of the struct Graph is in the graph.c file. When you compile the cities.c file this definition is not visible. You need to move the definition to graph.h
struct Graph {
unsigned int **matrix;
int nodeCount;
};
As suggested by Blaze, the below definition is confusing. typedef struct Graph * Graph. A better solution would be to
typedef struct Graph Graph;
and then in the code you can use
int graphCreate(Graph **, int);
int graphAddPath(Graph *, int, int, unsigned int);
int graphRemovePath(Graph *, int, int);
int graphDestroy(Graph **);
The compiler message is pretty clear. The type is incomplete, which basically means that the compiler only knows that it exists a struct named Graph, but it does not know what it looks like. The consequence of this is that you cannot access the fields.
So, first you have to answer this question. Do you want the programmer that is using the library to be able to access the fields of Graph? If no, put the definition in the .c file. If yes, put the definition in the .h file.
One more thing to consider is typedef struct Graph * Graph. You're hiding an awful lot of information when typedefing a struct, and the same goes for when you are typedefing a pointer. Now you're doing both. My personal opinion is that you really should avoid doing this, unless the answer to the above question is "no".
My suggestion is, if you want the user of the library to be able to access the fields of struct Graph, remove the typedef completely. If you want to hide it from the user, code access functions, like this:
// cities.h
int getNodeCount(Graph g);
// cities.c
int getNodeCount(struct Graph * g) {
return g->nodeCount;
}
And use it like this:
Graph g;
int nodeCount = getNodeCount(g);
Do note that i did NOT use the typedef in the function definition. Only in it's prototype.

Co-Dependent Definitions in C

Suppose we have a function pointer on a struct, which has the struct itself as the first argument, a typical callback scenario.
typedef void (*callback_type)(my_struct_type *mst, int whatever);
typedef struct {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;
This produces a compiler error on the first typedef, as one might expect. error: unknown type name my_struct_type. Reversing the definitions produces the same result, but the unknown type is callback_type.
The easy solution is to do the following:
typedef struct my_struct_type_S {
// lots of fun stuff
void (*notify_me)(my_struct_type_S *mst, int whatever);
} my_struct_type;
However, doing this elides the function pointer type definition, which it would be nice to be able to easily refer to later, and use for static type checks, nice error messages, etc.
Any suggestions on how to resolve this?
Edit on "possible duplicate":
This scenario involves function pointer typedefs that are arcane to many people. I think this is a good example for that case, and additionally, the accepted answer is very clean, clear, and simple.
You can do this by giving the struct a tag and using a forward declaration of the struct. Then you can use the typedef for the function pointer, and subsequently complete the definition of the struct.
typedef struct my_struct_type_S my_struct_type;
typedef void (*callback_type)(my_struct_type *mst, int whatever);
struct my_struct_type_S {
// lots of fun stuff
callback_type notify_me;
};
You need to define the tag of the struct
typedef void (*callback_type)(struct _my_struct_type *mst, int whatever);
typedef struct _my_struct_type {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;

C struct/function cross reference

So I'm morelikely running in a cross reference issue in C
Hello, (I couldnt write it in first for some reason)
Basicly this code:
structA.h:
#pragma once
#include "structB.h"
typedef struct
{
B b;
}A;
structB.h:
#pragma once
#include "structA.h"
typedef struct
{
int field;
}B;
void func(A* a);
structB.c:
#include "structB.h"
void func(A* a)
{
}
Produce the follwing errors on VC2010:
structa.h(7): error C2016: C requires that a struct or union has at
least one member structa.h(7): error C2061: syntax error : identifier
'B' etc
so since I only have a pointer to A in func(A* a) I try doing a forward declaration like this:
#pragma once
typedef struct A;
typedef struct
{
int field;
}B;
void func(A* a);
and I add #include "structA.h" in structB.c
However this doesnt work, to fix it I have to change the param of func(A* a) to func(struct A* a) in prototype and implementation...
But in this case i lose the purpose of typedef-ing my structs...
I know i could simply move the function to another file, but the function is related to my structure so I'd like to keep the prototype in the same file than my struct.
Now maybe thats not a good way to do thing in C, i'm mostly used to C++ so i tend to think in C++ when doing C wich is often problematic...
Does someone know a workaround? Thank you very much.
typedef struct structA;
How did this even compile? -- Correctly:
typedef struct A A;

Referencing a typedef as its struct counterpart

Ok guys, we all know there are all lot of typedef/struct questions out there, but I feel this one is a bit of a mind bender.
I'm simulating the neighbor interactions of a crystal lattice using strictly C. I have a struct called "ball_struct" which I typedef'ed as just "ball". The struct contains a pointer to a list of ball_structs (since I couldn't use the typedef name before its own declaration) that the ball considers its neighbors.
So here's the catch: I want to add balls to this list of list of ball_struct neighbors. When I compile (in Visual Studio 2009, no CLR support) I get:
error C2440: '=' : cannot convert from 'ball *' to 'ball_struct'
I'm not surprised, but I am stumped. Is there a way to cast the typedef back down to its respective struct? If not, is there anyway I can add a "ball" to a "ball_struct" list so I don't have to remove the typedef and paste "struct" keywords all over my code? Here's the code in question:
The struct / typedef:
typedef struct ball_struct
{
double mass;
vector pos, vel, acc;
/* keep list of neighbors and its size */
struct ball_struct *neighbors;
int numNeighbors;
} ball;
And the erroneous function:
/* adds ball reference to the neighbor list of the target */
void addNeighbor(ball *target, ball *neighbor)
{
int n = target->numNeighbors;
target->neighbors[n] = neighbor; // error C2440
target->numNeighbors = n+1;
}
Thanks, any help is appreciated. Remember, only solutions for C please.
On the line where you get the error:
target->neighbors[n] = neighbor;
you're assigning a pointer (neighbor) to an actual structure (not a pointer to a structure). Note that if you look at the error message carefully, you'll see that this is what it's saying. Note the asterisk in the 'from' type it talks about:
cannot convert from 'ball *' to 'ball_struct'
Assuming that target->neighbors points to an array of ball_struct structures, I think what you want to do is:
target->neighbors[n] = *neighbor;
PS: you may want to consider using the same name for your struct and the typedef of the struct:
typedef struct ball
{
/* etc... */
} ball;
While pre-ANSI compiler might not have supported that (Why are structure names different from their typedef names?), it's certainly well-supported today. And I think it makes things slightly less confusing.

What is forward reference in C?

What is forward reference in C with respect to pointers?
Can I get an example?
See this page on forward references. I don't see how forward referencing would be different with pointers and with other PoD types.
Note that you can forward declare types, and declare variables which are pointers to that type:
struct MyStruct;
struct MyStruct *ptr;
struct MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
// Or:
typedef struct MyStruct MyStruct;
MyStruct *ptr;
MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
I think this is what you're asking for when dealing with pointers and forward declaration.
I think "forward reference" with respect to pointers means something like this:
struct MyStruct *ptr; // this is a forward reference.
struct MyStruct
{
struct MyStruct *next; // another forward reference - this is much more useful
// some data members
};
The pointer is declared before the structure it points to is defined.
The compiler can get away with this because the pointer stores an address, and you don't need to know what is at that address to reserve the memory for the pointer.
Forward reference is when you declare a type but do not define it.
It allows you to use the type by pointer (or reference for C++) but you cannot declare a variable.
This is a way to say to the compiler that something exists
Say that you have a Plop structure defined in Plop.h:
struct Plop
{
int n;
float f;
};
Now you want to add some utility functions that works with that struct. You create another file PlopUtils.h (let's say you can't change Plop.h):
struct Plop; // Instead of including Plop.h, just use a forward declaration to speed up compile time
void doSomething(Plop* plop);
void doNothing(Plop* plop);
Now when you implement those function, you will need the structure definition, so you need to include the Plop.h file in your PlopUtils.cpp:
#include "PlopUtils.h"
#include "Plop.h" // now we need to include the header in order to work with the type
void doSomething(Plop* plop)
{
plop->n ...
}
void doNothing(Plop* plop);
{
plop->f ...
}
I think the C compiler originally had a pass in which it did symbol table building and semantic analysis together. So for example:
....
... foo(a,b) + 1 ... // assumes foo returns int
....
double foo(double x, double y){ ... } // violates earlier assumption
to prevent this, you say:
double foo(double x, double y); // this is the forward declaration
....
... foo(a,b) + 1 ... // correct assumptions made
....
double foo(double x, double y){ ... } // this is the real declaration
Pascal had the same concept.
Adding to previous answers. The typical situation in which forward reference is mandatory is when a struct foo contains a pointer to a struct bar, and bar contains a pointer to foo (a circular dependency between declarations). The only way to express this situation in C is to use a forward declaration, i.e.:
struct foo;
struct bar
{
struct foo *f;
};
struct foo
{
struct bar *b;
};
Forward references allow C compiler to do less passes and significantly reduces compilation time. It is probably was important some 20 years ago when computers was much slower and compliers less efficient.

Resources