Martin_H wrote:
Code:
struct _Cell;
typedef struct _Cell Cell;
lysp.c(84): Warning: Declaration does not declare anything
You already got the solution for the errors, but I wanted to add some information. This applies to standard C compilers, I know there are some differences in cc65 so I'm not sure if this is useful in this context.
The first line in that code snippet doesn't declare anything. The name that follows the "struct" is the name of the struct type. This can be followed by a list of members, or a name of a variable if the compiler already knows which members are in the struct. If you follow the struct keyword with just the name of a struct type, it doesn't give the compiler any new information, so it gives you a warning because it thinks you may have forgotten something. A line that just contains "struct _Cell" is like a line with just "int;" in it.
The second line tells the compiler that your custom type "Cell" is the same as a "struct _Cell". Even if you haven't given the compiler a member list for struct _Cell, it's okay to declare an equivalent type. It's even okay to declare a pointer to a Cell or a struct _Cell, but you can't declare a variable of the struct until the compiler knows what members it has.
In fact, declaring a struct type and using pointers to them without letting the compiler know what the members are, is called "opaque structs" and is a great way to implement object-oriented software in C. Example:
Code:
/* xyz.h */
typedef struct xyz *pxyz;
/* Create an instance of struct xyz */
pxyz xyz_Create(void);
/* Destroy an instance of struct xyz */
void xyz_Destroy(pxyz p);
/* Some operation on an instance of struct xyz */
void xyz_Rotate(pxyz p);
/* Print a struct xyz */
void xyz_Print(pxyz p);
Code:
/* xyz.c */
#include <stdio.h>
#include "xyz.h"
struct xyz
{
int x;
int y;
int z;
};
/* Create an instance of struct xyz */
pxyz xyz_Create(void)
{
pxyz result = calloc(1, sizeof(*pxyz));
if (result)
{
result->x = 1;
result->y = 2;
result->z = 3;
}
return result;
}
/* Destroy an instance of struct xyz */
void xyz_Destroy(pxyz p)
{
free(p);
}
/* Some operation on an instance of struct xyz */
void xyz_Rotate(pxyz p)
{
if (p)
{
int r = p->x;
p->x = p->y;
p->y = p->z;
p->z = r;
}
}
/* Print a struct xyz */
void xyz_Print(pxyz p)
{
if (p)
{
printf("x=%d, y=%d, z=%d\n", p->x, p->y, p->z);
}
else
{
printf("NULL\n");
}
}
Code:
/* abc.c */
#include "xyz.h"
int main(void)
{
/*
* A pointer to a struct xyz. Note that this module has no idea what members are in there!
*/
pxyz p = xyz_Create( );
xyz_Print(p); /* x=1, y=2, z=3 */
xyz_Rotate(p);
xyz_Print(p); /* x=2, y=3, z=1 */
xyz_Destroy;
/*
* Note: p is now a dangling pointer. Exercise for the reader: change the xyz_Destroy
* function so that it changes p to NULL. Take care that it does the right thing if
* pass NULL pointers to the function.
*/
}