I am trying to define a struct type (call it thing) that has a function pointer in it (call it bar), and I want that function to take an argument that is a pointer to an object of type thing.
I know from here that I can either do a forward declaration or declare the struct type in the argument list of the function pointer as shown here:
// In header
typedef struct thing thing_type;
typedef struct
{
int a;
int b;
double (*bar)(thing_type *t)
} thing;
OR
// In header
typedef struct
{
int a;
int b;
double (*bar)(struct thing *t)
} thing;
But when I go to initialize these values, I always get an incompatible pointer type warning.
double bar1(thing *t);
double bar2(thing *t);
// In main()
thing foo = {1, 2, bar1}; // WARNING
initialization of ‘double (*)(struct thing *)’ from incompatible pointer type ‘double (*)(thing *)’ [-Wincompatible-pointer-types]
foo.bar = bar2; // WARNING
passing argument 1 of ‘foo->bar’ from incompatible pointer type [-Wincompatible-pointer-types]
My code works the way I intend it to as far as I can tell through testing, but I would like to understand if I am doing anything "wrong" here or if there is a way to do what I want without throwing warnings for every assignment.
Note that thing foo = {1, 2, &bar1 }; (passing the address of a function pointer) makes no difference for this warning.
CodePudding user response:
In this code:
typedef struct thing thing_type;
typedef struct
{
int a;
int b;
double (*bar)(thing_type *t)
} thing;
the first typedef
defines thing_type
to be an alias for struct thing
, and the second typedef
defines thing
to be an alias for a structure with no tag. This second alias, thing
, has no relationship with the first alias, thing_type
, or with its structure type, struct thing
. In particular, there is no connection between the two types thing
and struct thing
.
Similarly, in this code:
typedef struct
{
int a;
int b;
double (*bar)(struct thing *t)
} thing;
the typedef
defines thing
to be an alias for a structure with no tag, and bar
is declared to be a pointer to a function with a parameter type of struct thing *
. Again, there is no connection between the two types thing
and struct thing
.
To refer to the same structure type in multiple places, you must use a tag for it. This is as simple as:
// Use the structure tag while defining the structure:
typedef struct MyTag
{
int a;
int b;
double (*bar)(struct MyTag *);
} MyAlias;
or:
// Define an alias first, then the structure definition can use the alias:
typedef struct MyTag MyAlias;
struct MyTag
{
int a;
int b;
double (*bar)(MyAlias *);
};