This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Undefined behavior or gcc is doing additional good job?
- From: "Bin.Cheng" <amker dot cheng at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Tue, 7 Jan 2014 16:01:23 +0800
- Subject: Re: Undefined behavior or gcc is doing additional good job?
- Authentication-results: sourceware.org; auth=none
- References: <CAHFci29VzKWxY37Zimq+GE_o4VbC=17cOqfVHu5F_fmsYragmA at mail dot gmail dot com> <20140103082427 dot GS892 at tucnak dot redhat dot com> <CAHFci29L6PS3ZSmM4X+2CcAxofgUXAyMw-bkqkAasFAwySDrXA at mail dot gmail dot com> <20140103091735 dot GX892 at tucnak dot redhat dot com>
On Fri, Jan 3, 2014 at 5:17 PM, Jakub Jelinek <jakub@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.