views:

28

answers:

1

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.

+3  A: 

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.

Michael Burr
Or you could just have `typedef struct { ... } ball;` — but then you can't refer to `struct ball`, only `ball`.
detly
Well, I guess that just turned out to be an excessive rant about overlooking the obvious and over-thinking my problems. That fixed it, thanks!
Brad
@Brad: I should probably also ask if you have allocated space (using `malloc()` or `calloc()`, for example) for the array of `struct ball_struct` that `neighbors` is pointing to?
Michael Burr
Yeah, I took care of that. Thanks for your concern and follow through.
Brad