-
Notifications
You must be signed in to change notification settings - Fork 210
Additional macro to iterate over list #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Neither list_for_each, nor list_for_each_safe allow user to iterate over a list if the structure of its elements is opaque. List_for_each_opaque provides said functionality, for opaque structures pointers to which can be safely cast to `struct node_list *`. In other words if the corresponding `struct node_list` field is placed at the top of the structure declaration.
On Wed, 16 Nov 2011 03:07:29 -0800, ndreys reply@reply.github.com wrote:
Interesting. The limitation that the list struct be the first member Should we go for a more generic wrapper, like so:
Where off == 0 is your case. That at least makes the user realize their
Your run.c patch was fine. run-with-debug.c defines CCAN_LIST_DEBUG I will fix it now to be clearer, ie:
As to examples, you need to have an Example: header so it can be found Thanks! |
Rusty Russell
You make a "Damn, why didn't I think of this?" kind of point. I'll
I can attest to that it is Then indeed. My initial comment had an Andrey Smirnov |
On Sun, 20 Nov 2011 21:53:29 -0800, ndreys reply@reply.github.com wrote:
Thanks!
Indeed, it spits out what it tried, but that butterfly effect is nasty I think if you rewrite it it'll make things easier; you should be able Thanks, |
This is a second attempt at implementing iteration through list of opaque structures. It is based on suggestion from Rusty Russel: >> Neither list_for_each, nor list_for_each_safe allow user to iterate >> over a list if the structure of its elements is opaque. >> List_for_each_opaque provides said functionality, for opaque >> structures pointers to which can be safely cast to `struct >> node_list *`. In other words if the corresponding `struct >> node_list` field is placed at the top of the structure declaration. > > Interesting. The limitation that the list struct be the first member > makes this dangerous to use, though. > > Should we go for a more generic wrapper, like so: > > > list_for_each_off(h, i, off) > > Where off == 0 is your case. That at least makes the user realize their > implicit assumption, and may allow the others to be implemented in terms > of that macro (using offsetof() and typeof()?)... >
Just adding `-g' to list of CFLAGS doesn't make gcc to generate debug information required for macro expansion during debugging. Replacing it with `-g3 -ggdb' rectifies this.
The last commit is completely unrelated. But it was really annoying not to be able to expand macros in gdb and I didn't want to open a separate pull request for such a small change. Feel free to ask me to discard it. |
This is an addendum to previous commit which didn't fix the issue in all the required places.
On Tue, 22 Nov 2011 02:20:27 -0800, ndreys reply@reply.github.com wrote:
OK, I'll review the combined list_for_each_off() patch here. Since it's
I wouldn't cast to ptrdiff_t here; it allows them to pass anything as I also would avoid the __ prefix; I like it, but reserved-word-pedants Finally, I think it's clearer as list_node_from_off_ and list_node_to_off_: static inline void *list_node_to_off_(struct list_node *node, size_t off) static inline struct list_node *list_node_from_off_(void *ptr, size_t off)
Because these are all macros, we can order them any way we like. Thus I
Use offsetof() here, instead of sizeof(const char *). More explicit.
This becomes (untested); #define list_for_each_off(h, i, off)
Implement of container_of_var_off() as a separate patch?
Prefer list_for_each_safe_off(), but that's a bit arbitrary.
This isn't really opaque though, is it? There are two ways to make it really opaque. One is to never define it The latter gives you a more realistic test. Thanks, |
There is are certain use-cases when it is necessary to know the offset of the member in a structure's memory layout. One such use-case can be seen in `ccan/list/list.h' in macros `list_for_each' and `list_for_each_safe'. This commit implements said functionality with `container_of_var_off' macro.
See #1 (comment) for details.
On Wed, 23 Nov 2011 15:45:19 -0800, Rusty Russell reply@reply.github.com wrote:
Oh, please do, it is far more likely that my code will only improve from
Yes I suspected that this might be an issue. I just didn't know to
Agree that is probably a better idea, but, I am afraid that now I would BTW, I didn't put any documentation for those function, seeing how they
That very well might be true, and I've reordered them, but as I recently
Done.
First way doesn't seem to be any close to real life usage, so I forgo Andrey Smirnov |
On Sun, 27 Nov 2011 09:16:04 -0800, ndreys reply@reply.github.com wrote:
Haven't yet; inline is such a common option. If/when we do, we add
No, I reserve the kerneldoc-style comments for public functions.
No, you're right. ccanlint tries several things to compile Examples,
Good point. Writing a ccanlint man page with all this is on my TODO Cheers, |
Rusty, I hope we aren't deadlocked waiting for each others actions, are we? Because I am waiting for you to comment on my latest code, so that I can fix all the issues and make the whole thing good enough for inclusion. Andrey Smirnov |
On Sat, 10 Dec 2011 13:18:13 -0800, ndreys reply@reply.github.com wrote:
We did: thanks for breaking it :) I took your changes and re-factored them into three commits:
I've uploaded now... Thanks! |
Done, thanks! |
Neither list_for_each, nor list_for_each_safe allow user to iterate
over a list if the structure of its elements is opaque.
List_for_each_opaque provides said functionality, for opaque
structures pointers to which can be safely cast to
struct node_list *
. In other words if the correspondingstruct node_list
field is placed at the top of the structure declaration.P.S. I tried my best to figure out how the testing infrastructure
works, but I'm afraid I wasn't completely successful. I added my tests
to run.c, but the purpose of run-with-debug.c(looks completely
identical) and the mechanics behind using "Examples" section of
documentation for testing completely evade me. So for now I just
ignored them but if it's necessary I'll add tests there.