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: Jakub Jelinek <jakub at redhat dot com>
- To: "Bin.Cheng" <amker dot cheng at gmail dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Fri, 3 Jan 2014 09:24:27 +0100
- 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>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, Jan 03, 2014 at 04:12:19PM +0800, Bin.Cheng wrote:
> Hi, For below simple example:
> #include <stdint.h>
>
> 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
memset (__bss_start, 0, (uintptr_t) __data_start - (uintptr_t) __bss_start);
(note the cases to non-pointers), then it is just implementation defined
behavior. Or do
uint32_t data_ptr;
asm ("" : "g" (data_ptr) : "0" (__data_start));
for (uint32_t* bss_ptr = __bss_start; bss_ptr != data_ptr; ++bss_ptr) {
*bss_ptr = 0;
}
and thus hide from the compiler the fact that __data_start is in a different
object.
Jakub