:Is the following portable and safe?
:
:Given n different structure declarations, where each structure begins
:with the same member type, can any instance of any of the structures
:be cast to the (pointer) type of the first member?
:
:e.g.
:
: struct foo {
: const char *s;
: ...
: };
:
: struct bar {
: const char *s;
: ...
: };
:
: int gefahr(struct foo *Foo, struct bar *Bar) {
: return strcmp((const char *s)Foo, (const char *s)Bar);
: }
:
:Likewise if the first member were a more complex data type, but
:nevertheless the same between the different structures.
:
:It seems safe to me, but I can't explain why :-)
:
:Cheers,
Probably safe, but not a good idea. Why not simply pass blah->s
to the routine instead? One trick I use, when a subroutine needs
the first N headers of a structure, is create an embedded 'header'
structure:
struct base {
a
b
c
}
struct fubar1 {
struct base base;
x
y
z
}
struct fubar2 {
struct base base;
h
i
j
}
struct fubar3 {
...
}
callsomesubroutine(&fubar2->base);
The calling direction is not the problem. It's the return value that
is usually a problem. For example, a doubly-linked list function might
look like this:
void *
getNextNode(Node *previousNode)
{
return(previousNode->next);
}
struct fubar {
Node node;
...
}
struct fubar *fu;
for (fu = getHeadOfList(&List); fu; fu = getNextNode(&fu->node)) {
}
There are ways around this, at least if the contents of a list is
uniform. FreeBSD's kernel's /usr/src/sys/sys/queue.h implements
macros for all of its list functions that actually create special node
structures with previous and next pointers of exactly the proper type
for however they are used. I generally use the 'void *' return value
trick myself, to make the code more readable at the cost of a slight
loss in type checking. But I only use it for return values... arguments
are still required to be the proper exact type.
-Matt
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message