[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git
Subject:    Re: [PATCH v2 18/19] OFFSETOF_VAR macro to simplify hashmap iterators
From:       Junio C Hamano <gitster () pobox ! com>
Date:       2019-09-30 16:58:33
Message-ID: xmqqy2y5hgau.fsf () gitster-ct ! c ! googlers ! com
[Download RAW message or body]

Eric Wong <e@80x24.org> writes:

> While we cannot rely on a `__typeof__' operator being portable
> to use with `offsetof'; we can calculate the pointer offset
> using an existing pointer and the address of a member using
> pointer arithmetic.

> +/*
> + * like offsetof(), but takes a pointer to type instead of the type

It actually takes "a pointer to a variable of the type".  I had to
read the above twice to guess what is going on.

> + * @ptr is subject to multiple evaluation since we can't rely on TYPEOF()
> + */
> +#define OFFSETOF_VAR(ptr, member) \
> +	((uintptr_t)&(ptr)->member - (uintptr_t)(ptr))
> +

This unfortunately has funny interactions with using uninitialized
variables.  "make CC=clang config.o" gives something like this:

config.c:1944:50: error: variable 'entry' is uninitialized when used here
      [-Werror,-Wuninitialized]
        hashmap_for_each_entry(&cs->config_hash, &iter, entry,
                                                        ^~~~~
./hashmap.h:453:20: note: expanded from macro 'hashmap_for_each_entry'
                                                OFFSETOF_VAR(var, member)); \
                                                             ^~~
./git-compat-util.h:1346:16: note: expanded from macro 'OFFSETOF_VAR'
        ((uintptr_t)&(ptr)->member - (uintptr_t)(ptr))
                      ^~~
./hashmap.h:445:61: note: expanded from macro 'hashmap_iter_first_entry_offset'
        container_of_or_null_offset(hashmap_iter_first(map, iter), offset)
                                                                   ^~~~~~
config.c:1939:34: note: initialize the variable 'entry' to silence this warning
        struct config_set_element *entry;
                                        ^
                                         = NULL

Personally, I feel the workaround suggested by the compiler is just
as bogus as the warning itself X-<.  Casting NULL as if it were a
pointer to an object of type typeof(*ptr), treating it as if it is a
valid address, and doing raw address arith is just as bogus as doing
the same raw address arith on an uninitialized ptr, isn't it?

Anyway...
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic