Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #159318
| Message-ID | <pgfthh-to3.ln1@wilbur.25thandClement.com> (permalink) |
|---|---|
| From | William Ahern <william@25thandClement.com> |
| Subject | Re: container_of macro... |
| Newsgroups | comp.lang.c |
| References | <s26io0$nne$1@gioia.aioe.org> <j4plhh-vnt1.ln1@wilbur.25thandClement.com> <20210309194126.744@kylheku.com> |
| Date | 2021-03-12 17:01 -0800 |
Kaz Kylheku <563-365-8930@kylheku.com> wrote:
> On 2021-03-10, William Ahern <william@25thandClement.com> wrote:
>> Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
>>> Its been a while since I used the container_of macro, however, it can
>>> come in handy wrt creating linked data-structures. Here is an example I
>>> coded up, just to see if I could do it from scratch, after all these years:
>>
>> The biggest problem with container_of is that it's not typesafe. I never
>> understood why the GNU and Linux ecosystem adopted that approach instead of
>> the classic BSD macros:
>>
>> https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/sys/queue.h
>
> There is virtually no difference; that approach is exactly the
> container_of approach.
>
> Like container_of, there are macros which are given the name of a
> structure member and calcluate offsets.
>
> For instance:
>
> SLIST_FOREACH(TYPE *var, SLIST_HEAD *head, SLIST_ENTRY NAME);
>
> looks to me exactly like doing:
>
> for_each_node(N, HEAD) {
> TYPE *var = container_of(TYPE, N, NAME);
>
> }
>
> we walk over a list, and then map each node back to a containing
> object by assuming it is embedded as a member called NAME.
The difference is that container_of takes an explicit type name and casts
the pointer in a way that almost completely subverts type checking. Your
pseudocode above obscures that critical difference.
In general in <sys/queue.h> only *LIST_HEAD and *LIST_ENTRY take explicit
type names. They generate struct definitions which the rest of the API is
carefully designed to avoid casting into oblivion. Almost everywhere else
you only pass object pointers and a field name. Any type mismatches are
caught by the compiler.
The exception is TAILQ, where TAILQ_LAST, TAILQ_PREV, and
TAILQ_FOREACH_REVERSE takes the type name of head. I used to prefer CIRCLEQ
as it offered all the same interfaces without requiring a type name, but the
BSDs removed CIRCLEQ some years ago when it was realized that the
implementation required violating aliasing rules. Fortunately it's rare that
I ever need reverse iteration.
container_of could be made more type safe by dropping the type name argument
and relying on __typeof__ instead. I never understood why it didn't
considering its provenance--Linux kernel hackerdom, where GCC extensions are
commonly relied upon. Most major compilers have supported GCC's __typeof__
extension for decades, including MSVC, SunPro, and xlC. (CIRCLEQ also could
have been rehabilitated using __typeof__, but the BSDs decided to just drop
it entirely.)
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
container_of macro... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-03-08 17:24 -0800
Re: container_of macro... Öö Tiib <ootiib@hot.ee> - 2021-03-09 02:06 -0800
Re: container_of macro... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-03-10 17:02 -0800
Re: container_of macro... Kaz Kylheku <563-365-8930@kylheku.com> - 2021-03-09 15:59 +0000
Re: container_of macro... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-03-09 17:35 +0000
Re: container_of macro... Kaz Kylheku <563-365-8930@kylheku.com> - 2021-03-09 17:51 +0000
Re: container_of macro... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-03-10 17:13 -0800
Re: container_of macro... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-03-10 17:05 -0800
Re: container_of macro... William Ahern <william@25thandClement.com> - 2021-03-09 18:56 -0800
Re: container_of macro... Kaz Kylheku <563-365-8930@kylheku.com> - 2021-03-10 03:47 +0000
Re: container_of macro... William Ahern <william@25thandClement.com> - 2021-03-12 17:01 -0800
Re: container_of macro... Jim <jim.cromie@gmail.com> - 2021-03-16 22:14 -0700
Re: container_of macro... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-03-10 17:07 -0800
csiph-web