On Fri, Jan 3, 2014 at 5:17 PM, Jakub Jelinek <ja...@redhat.com> wrote: > On Fri, Jan 03, 2014 at 04:44:48PM +0800, Bin.Cheng wrote: >> >> extern uint32_t __bss_start[]; >> >> extern uint32_t __data_start[]; >> >> >> >> void Reset_Handler(void) >> >> { >> >> /* Clear .bss section (initialize with zeros) */ >> >> for (uint32_t* bss_ptr = __bss_start; bss_ptr != __data_start; >> >> ++bss_ptr) { >> >> *bss_ptr = 0; >> >> } >> >> } >> > >> > I believe this is undefined behavior, so GCC can assume >> > bss_ptr != __data_start is true always. You need something like >> Sorry for posting the premature question. Since both __bss_start and >> __data_start are declared as array, it seems there is no undefined >> behavior, the check is between two pointers with same type actually, > > I think this has been discussed in some PR, unfortunately I can't find it. > If it was < or <=, then it would be obvious undefined behavior, those > comparisons can't be performed between different objects, the above is > questionable, because you still assume that you get through pointer > arithmetics from one object to another one, without dereference pointer > arithmetics can be at one past last entry in the array, but whether that is > equal to the object object is still quite problematic. Sorry for late replying. It seems equality operators allow two pointers to compare equal if one pointer is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space. Then the "!=" condition can't be always true in the example.
> >> right? So the question remains, why GCC would clear the two lower >> bits of " __data_start - __bss_start" then? Am I some stupid mistake? > > That said, if either of __bss_start of __data_start aren't 32-bit aligned, > then it is a clear undefined behavior, the masking of low 2 bits (doesn't > happen on x86_64) comes from IVopts computing the end as > ((__data_start - __bss_start) + 1) * 4 and the __data_start - __bss_start > is exact division by 4, apparently we don't fold that back to just > (char *) __data_start - (char *) __bss_start + 4. Em, YES, it comes from ivopt rewriting, but, if it's not undefined behavior, won't it be annoying (or simply wrong) for compiler to do something not written by the code? Thanks, bin -- Best Regards.