[luau] C struct interdependency problem
Allens
allens at bigisland.net
Sat Jun 22 21:05:01 PDT 2002
Hi all, I've been lurking a while...
Ray,
As always one wonders... well what are you really trying to do... why
not use C++ for such a structure is what I wonder. But if it's because you
prefer C or whichever.
Also I wonder why you want the syntax syle of
typedef struct Object Object... it's more common to create like this:
typedef struct Object_t
{
Error superClass;
} Object;
This is all in one step. If you do it in two steps, it's still most common,
I think, to use:
struct Object_t
{
Error superClass;
};
then subsequently the typedef is easier to read (at least for me):
typedef struct Object_t Object;
The thing is, the type being declared is an Object_t (the structs "tag" is
Object_t), and the new type is just "Object".
ObjectError
Object
Error
LinkedList/Stack (I'm assuming the stack.h file that has LinkedList means
that Stack is a LinkedList and it's a small typo)
The thing I'm looking at that might "not work out" is that you want Object
to have an Error member, and Error is a "subclass" of Object. The
definition you show cannot compile because when you create an Object you
declare an Object (which has an Object (which has an Object (and so on)
member) member as a member, so it is being told to have declare an infinite
number of Objects to declare a single object. You need to defer this
declaration with a pointer instead of a reference declaration so you can
create the member at runtime dynamically.
The place to make this indirection is the ObjectError member (the way you
have it set up). So I have that as a pointer to ObjectError (ObjectError
*pError). (see below).
When you create an Object like this
...
Object theinstance;
...
theinstance.pError will be an invalid value. You will have to set it to
NULL like this
theinstance.pError = 0; (or "=NULL;" if NULL is defined)
This is where C++ would come in handy because you could have a 'constructer'
that always cleared this value.
NOTE: this implies that you check for pError = 0, and use that to mean there
is no error. If you don't want that, and you really want a member there,
then after the declaration of "theinstance" you have to follow right away
with.
theinstance.pError = malloc(sizeof (ObjectError));
memset(theinstance.pError, 0, sizeof(ObjectError));
Note to use C++ you can write C code that you simply augment with C++
constructions when useful, generally there is no cost performance or other
cost if just using C++ for the C++ version of subclassing. The issue with
the pointer would be the same, but you would have the Object declared more
like this:
class Object
{
ObjectError *pError;
/* here you have a "constructor", which is called whenever an "Object"
is created */
Object()
{
pError = 0; /* this ensures that pError is always 0, then you can
test for theinstance.pError == 0 to mean there is no error at the moment */
};
};
Again, if you really don't want to check for the value equal to null (you
always want a real Error object as a member), then the constructor and class
declaration looks like this.
class Object
{
ObjectError *pError;
Object()
{
pError = new ObjectError();
}
~Object()
{
/* this is the destructor, I'm putting this in because if you
create the error on construction, you should dispose of it when you throw
the object away */
delete pError;
pError = NULL;
}
}
=======
this is the "see below" part! the C version of the answer
-----------
object.h
-----
#include "ObjectError";
typedef struct Object_t
{
ObjectError *pError;
...
}
-----
objecterror.h
-----
#include "error.h"
typedef struct ObjectError_t
{
Error super_class;
} ObjectError;
-----
error.h
-----
#include "stack.h"
typedef struct Error_t
{
Stack super_class;
} Error;
-----
stack.h
-----
typedef struct Stack_t
{
Object super_class;
} Stack;
-----
Hope this makes sense and is helpful. It gets involved quick, feel free to
ask me to explain something I've said, I didn't want to go off on too many
tangents (I already added in C++!).
-craig
----- Original Message -----
From: "Ray Strode" <halfline at hawaii.rr.com>
To: <luau at videl.ics.hawaii.edu>
Sent: Friday, June 21, 2002 6:31 AM
Subject: [luau] C struct interdependency problem
> Hi everyone.
>
> I have a question about getting the compiler to grok some files with
> interdependent structs.
>
> I've got something basically like this:
>
> object.h
> -----------
> ...
> typedef struct Object Object;
> typedef struct ObjectError ObjectError;
> ...
> struct ObjectError {
> Error super_class;
> ...
> };
> ...
> struct Object {
> ObjectError *error;
> ...
> };
> ...
>
> error.h
> ---------
> ...
> typedef struct Error Error;
> ...
> struct Error {
> Stack super_class;
> ...
> };
> ...
>
> stack.h
> ----------
> ...
> typedef struct LinkedList LinkedList;
> ...
> struct LinkedList {
> Object superclass;
> ...
> };
> ...
>
> So basically the dependency tree is this:
>
> +-----Object-----+<----+
> |/////has-a://///| |
> |//////...///////| |
> |//ObjectError///| |
> |//////...///////| |
> +----------------+ |
> +--------------+
> |
> .
> +---LinkedList---+<----+
> |/////has-a://///| |
> |//////...///////| |
> +----------------+ |
> +--------------+
> |
> .
> +-----Stack------+<----+
> |/////has-a://///| |
> |//////...///////| |
> +----------------+ |
> +--------------+
> |
> .
> +--ObjectError---+
> |/////has-a://///|
> |//////...///////|
> +----------------+
>
> Any idea how I can get this setup arranged so the compiler
> believes everything is alright (e.g. where should the #includes
> go and things)?
>
> --Ray
>
> _______________________________________________
> LUAU mailing list
> LUAU at videl.ics.hawaii.edu
> http://videl.ics.hawaii.edu/mailman/listinfo/luau
>
More information about the LUAU
mailing list