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.

Reply via email to