On Fri, Feb 11, 2022 at 7:21 AM Yonghong Song <yhs@xxxxxx> wrote: > > struct bpf_spin_lock { > __u32 val; > }; > struct bpf_timer { > __u64 :64; > __u64 :64; > } __attribute__((aligned(8))); > > The initialization code: > *(struct bpf_spin_lock *)(dst + map->spin_lock_off) = > (struct bpf_spin_lock){}; > *(struct bpf_timer *)(dst + map->timer_off) = > (struct bpf_timer){}; > It appears the compiler has no obligation to initialize anonymous fields. > For example, let us use clang with bpf target as below: > $ cat t.c > struct bpf_timer { > unsigned long long :64; > }; > struct bpf_timer2 { > unsigned long long a; > }; > > void test(struct bpf_timer *t) { > *t = (struct bpf_timer){}; > } > void test2(struct bpf_timer2 *t) { > *t = (struct bpf_timer2){}; > } > $ clang -target bpf -O2 -c -g t.c > $ llvm-objdump -d t.o > ... > 0000000000000000 <test>: > 0: 95 00 00 00 00 00 00 00 exit > 0000000000000008 <test2>: > 1: b7 02 00 00 00 00 00 00 r2 = 0 > 2: 7b 21 00 00 00 00 00 00 *(u64 *)(r1 + 0) = r2 > 3: 95 00 00 00 00 00 00 00 exit wow! Is this a clang only behavior or gcc does the same "smart" optimization? We've seen this issue with padding, but I could have never guessed that compiler will do so for explicit anon fields. I wonder what standard says and what other kernel code is broken by this "optimization".