On 22/09/16 16:20, paul.kon...@dell.com wrote: > >> On Sep 22, 2016, at 11:16 AM, David Brown <da...@westcontrol.com> wrote: >> >> On 22/09/16 16:57, paul.kon...@dell.com wrote: >>> >>>> On Sep 22, 2016, at 6:17 AM, David Brown <da...@westcontrol.com> wrote: >>>> >>>> ... >>>> Your trouble is that your two pointers, cur and end, are pointing at >>>> different variables. Comparing two pointers that are independent (i.e., >>>> not pointing to parts of the same aggregate object) is undefined - the >>>> compiler can assume that these two external objects could be anywhere in >>>> memory, so there is no way (in pure C) for you to know or care how they >>>> are related. Therefore it can assume that you will never reach "cur == >>>> end". >>> >>> Would making them intptr_t instead of pointers fix that? >>> >> >> With care, yes. But I think it still relies on gcc not being quite as >> smart as it could be. This seems to generate working code, but the >> compier could in theory still apply the same analysis: >> >> void rtems_initialize_executive(void) >> { >> uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin; >> uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end; > > I would not expect the compiler to apply pointer rules for code like this. > (u)intptr_t is an integer type; it happens to be one whose width is chosen to > match the width of pointers on the platform in question, but that doesn't > change the fact the type is integer. For example, it is perfectly valid for > an intptr_t variable to contain values that could not possibly be pointers on > a given platform. > > paul >
It sounds to me as these are the sort of optimizations that should be disabled when compiling with -ffreestanding. R.