You are right that it would work, but back solving for which alignment the compiler decided is hard. It's definitely whack-a-mole in that case. It could have very well decided 16 too. Without any insight as to why that breaks down. Or you go the route of putting alignments on structures just for that behavior which I consider not the best approach.
Well, we only need to pick an alignment *larger* than what the compiler decides, right? I'd hazard a guess that 8 would be enough for a long time (GCC probably just got confused between 32 and 64 bit modes or something... there's no other reason I could think of to explain this).
From that I'd conclude that if you did:
extern struct boot_state_init_entry _bs_init_begin[]; extern struct boot_state_init_entry _bs_init_end[];
for (cur = _bs_init_begin; cur < _bs_init_end; cur++) ...
the compiler shouldn't be able to guarantee that the first array wasn't empty and therefore pointing to "one after the end" which is the start of the next array in the first iteration.
I think you are right on that point -- using '<' instead of equality. But those aren't pointer types. Not sure if the spec things arrays like that are poitners or a separate type. Either way, hopefully there isn't some language in the spec that suggests comparisons like that can be optimized away.
The array degenerates to a pointer at that point AFAIK. You could also write &_bs_init_begin... for an array type the two should be pretty much equivalent.