I have two header files, namely point.h
and polygon.h
//point.h
#ifndef POINT_H
#define POINT_H
typedef struct Point point;
point *alloc_point(void);
int free_point(point *);
void init_point(point *, float, float);
void print_point(point *);
#endif
and
//polygon.h
#ifndef POLYGON_H
#define POLYGON_H
typedef struct Polygon polygon;
polygon *alloc_polygon(void);
int free_polygon(polygon *);
void init_polygon(polygon *, unsigned, point *);
void print_polygon(polygon *);
#endif
with the corresponding point.c
and polygon.c
files
//point.c
#include <stdlib.h>
#include <stdio.h>
#include "point.h"
struct Point
{
float x;
float y;
};
point *alloc_point(void)
{
point *pt = (point *)malloc(sizeof(point));
if (pt)
{
return pt;
}
else
{
fprintf(stderr, "Could not allocate point. Aborting\n");
exit(EXIT_FAILURE);
}
}
int free_point(point *pt)
{
if (pt)
{
free(pt);
pt = NULL;
return 1;
}
else
{
fprintf(stderr, "Could not free point. Aborting\n");
return 0;
}
}
void init_point(point *pt, float x, float y)
{
pt->x = x;
pt->y = y;
}
void print_point(point *pt)
{
printf("Point at (%f, %f)\n", pt->x, pt->y);
}
and
//polygon.c
#include <stdio.h>
#include <stdlib.h>
#include "point.h"
#include "polygon.h"
struct Polygon
{
unsigned nside;
point *centre;
};
polygon *alloc_polygon(void)
{
polygon *poly = (polygon *)malloc(sizeof(polygon));
if (poly)
{
return poly;
}
else
{
fprintf(stderr, "Cannot allocate polygon. Aborting\n");
exit(EXIT_FAILURE);
}
}
int free_polygon(polygon *poly)
{
if (poly)
{
free(poly);
poly = NULL;
return 1;
}
else
{
fprintf(stderr, "Cannot free polygon. Aborting\n");
exit(EXIT_FAILURE);
}
}
void init_polygon(polygon *poly, unsigned nside, point *centre)
{
poly->nside = nside;
poly->centre = centre;
}
void print_polygon(polygon *poly)
{
printf("%u-sided polygon with centre at (%f, %f)",
poly->nside, poly->centre->x, poly->centre->y);
}
When I try to run main.c
, which contains
#include <stdio.h>
#include "point.h"
#include "polygon.h"
int main() {
point *centre = alloc_point();
init_point(centre, 10.0, 10.0);
print_point(centre);
unsigned nside = 4;
polygon *poly = alloc_polygon();
init_polygon(poly, nside, centre);
print_polygon(poly);
free_point(centre);
free_polygon(poly);
return 0;
}
I get the error message (coming from the print_polygon
method inside polygon.c
)
error: dereferencing pointer to incomplete type 'point' {aka 'struct Point'}
I do not get that error as the definition of the Polygon
structure has a pointer to point
. Why can I not get the code running?
P.S.: I use gcc 8.1.0 and compile using
gcc -Os -Wall -Wextra -Wpedantic -Werror -std=c99 .\main.c .\point.c .\polygon.c -o .\main.exe
In poly -> centre -> x
, poly -> centre
is a pointer to a point
, and -> x
dereferences that point
, but polygon.c
does not have a complete definition of point
. It only knows point
is struct Point
but not what the contents of struct Point
are.
Some options to fix this are:
point.c
that will print the point’s coordinates, export that routine from point.c
(via point.h
), and call it from print_polygon
.point.c
that will provide the coordinates, export that routine or routines, and call it or them from print_polygon
to get the values to print.struct Point
visible in polygon
.The first is best for preserving modularity.
(In 2, the coordinates could be provided by returning them from one routine in a structure whose definition is shared between point.c
and polygon.c
, by returning the two float
coordinates in separate routines, one for each, or by returning the two float
coordinates in float
objects passed by reference.)