N
Nick
I've been wrestling with my conscience over this one for several years
now. This is a cut down example of some code I've written to iterate
over any linked list as long as it satisfies a particular constraint.
But is it actually legal? - I can't make my mind up.
Here's roughly what it looks like. I could post the full code (it's
actually a mergesort rather than an iterator) if this has silly errors
in or doesn't explain it properly. But here goes:
I have a header file (list_header.h)
that just contains:
typedef void list_function(void *l);
void list_iterator(void *lst);
and a list code file like this:
#include "list_header.h"
struct generic_list {
struct generic_list *next;
};
void list_iterator(void *lst, list_function *lf) {
struct generic_list *p = lst;
while(*p) {
lf(p);
p = p->next;
}
}
Then, whenever you want to iterate over a list you do:
#include "list_header.h"
struct thislist {
struct thislist *next;
... lots of other fields ...
} *reallist;
void list_callback(void *l) {
struct thislist *lp = l;
... do things with all the other fields in lp ...
}
and then, deep in the bowels of the code, after reallist has been made
to point to a list of items
list_iterator(reallist,list_callback);
Now clearly if you ever use this with structures where the first item is
not a pointer to a list item you are heading for every type of error and
undefined behaviour.
But if not, is this legal? The dodgy bit is casting a pointer to one
type of list, via void, to another type of list and then dereferencing a
field within it and expecting it to point to another list of the second
type when it originally pointed to one of the first.
On the other hand, all the stuff I can read about the equivalence of
pointer suggests it just might be (it's clearly right on the border).
It works, has worked on various compilers and OSs, but I know that
proves absolutely nothing!
Thoughts?
now. This is a cut down example of some code I've written to iterate
over any linked list as long as it satisfies a particular constraint.
But is it actually legal? - I can't make my mind up.
Here's roughly what it looks like. I could post the full code (it's
actually a mergesort rather than an iterator) if this has silly errors
in or doesn't explain it properly. But here goes:
I have a header file (list_header.h)
that just contains:
typedef void list_function(void *l);
void list_iterator(void *lst);
and a list code file like this:
#include "list_header.h"
struct generic_list {
struct generic_list *next;
};
void list_iterator(void *lst, list_function *lf) {
struct generic_list *p = lst;
while(*p) {
lf(p);
p = p->next;
}
}
Then, whenever you want to iterate over a list you do:
#include "list_header.h"
struct thislist {
struct thislist *next;
... lots of other fields ...
} *reallist;
void list_callback(void *l) {
struct thislist *lp = l;
... do things with all the other fields in lp ...
}
and then, deep in the bowels of the code, after reallist has been made
to point to a list of items
list_iterator(reallist,list_callback);
Now clearly if you ever use this with structures where the first item is
not a pointer to a list item you are heading for every type of error and
undefined behaviour.
But if not, is this legal? The dodgy bit is casting a pointer to one
type of list, via void, to another type of list and then dereferencing a
field within it and expecting it to point to another list of the second
type when it originally pointed to one of the first.
On the other hand, all the stuff I can read about the equivalence of
pointer suggests it just might be (it's clearly right on the border).
It works, has worked on various compilers and OSs, but I know that
proves absolutely nothing!
Thoughts?