Hi,

How can the compiler in this case assume that endptr and str do not
point to the same array object?

ISO C99 6.5,8  Relational operators
5)
...
"If the expression P points to an element of an array object and the
expression Q points to the last element of the same array object,
the pointer expression Q+1 compares greater than P. In all other
cases, the behavior is undefined"

How does the compiler at compile time know that endptr which is
equivalent is to str[maxlen] is not within the
range of string declared by str?
Or in the terms of the above standard, how does it know that endptr is not Q+1?


Best regards,
Kjetil Oftedal



On Tue, 7 Jan 2025 at 13:38, Frank Mehnert
<frank.mehn...@kernkonzept.com> wrote:
>
> There is a longer discussion on stack overflow:
>
>   
> https://stackoverflow.com/questions/6702161/pointer-comparisons-in-c-are-they-signed-or-unsigned
>
> See the remarks about "comparison of pointers belonging to different
> objects".
>
> See also the remark in the LLVM ticket from 'nikic' about the overflow
> being the same case of undefined behavior. IMO this makes sense: If we
> add a huge offset to a pointer triggering an overflow, the compiler may
> indeed assume that the result does not point to the same object as the
> original pointer.
>
> Kind regards,
>
> Frank
>
> On Dienstag, 7. Januar 2025 13:29:33 MEZ Kjetil Oftedal wrote:
> > Hi,
> >
> > Can you point to where in the C standard this is treated as undefined 
> > behavior?
> >
> > Best regards,
> > Kjetil Oftedal
> >
> > On Tue, 7 Jan 2025 at 13:10, Marcus Haehnel
> > <marcus.haeh...@kernkonzept.com> wrote:
> > >
> > > From: Frank Mehnert <frank.mehn...@kernkonzept.com>
> > >
> > > It is undefined behavior to compare two pointers belonging to different
> > > objects. This includes the case where the addition overflows. Clang-20
> > > seems to follow this rule more eagerly and optimizes away the old test.
> > >
> > > Fix the test by performing the addition on uintptr_t values rather than
> > > on on char pointers.
> > >
> > > See also https://github.com/llvm/llvm-project/issues/121909.
> > >
> > > Signed-off-by: Marcus Haehnel <marcus.haeh...@kernkonzept.com>
> > > ---
> > >  libc/string/generic/strnlen.c | 6 ++++--
> > >  1 file changed, 4 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/libc/string/generic/strnlen.c b/libc/string/generic/strnlen.c
> > > index 4d4cde84f..82d4122ec 100644
> > > --- a/libc/string/generic/strnlen.c
> > > +++ b/libc/string/generic/strnlen.c
> > > @@ -29,15 +29,17 @@
> > >     '\0' terminator is found in that many characters, return MAXLEN.  */
> > >  size_t strnlen (const char *str, size_t maxlen)
> > >  {
> > > -  const char *char_ptr, *end_ptr = str + maxlen;
> > > +  const char *char_ptr, *end_ptr;
> > >    const unsigned long int *longword_ptr;
> > >    unsigned long int longword, himagic, lomagic;
> > >
> > >    if (maxlen == 0)
> > >      return 0;
> > >
> > > -  if (__builtin_expect (end_ptr < str, 0))
> > > +  if (__builtin_expect ((uintptr_t)str + maxlen < (uintptr_t)str, 0))
> > >      end_ptr = (const char *) ~0UL;
> > > +  else
> > > +    end_ptr = str + maxlen;
> > >
> > >    /* Handle the first few characters by reading one character at a time.
> > >       Do this until CHAR_PTR is aligned on a longword boundary.  */
> > > --
> > > 2.47.1
> > >
> > > _______________________________________________
> > > devel mailing list -- devel@uclibc-ng.org
> > > To unsubscribe send an email to devel-le...@uclibc-ng.org
> >
>
>
> --
> Dr.-Ing. Frank Mehnert, frank.mehn...@kernkonzept.com, +49-351-41 883 224
>
> Kernkonzept GmbH.  Sitz: Dresden.  Amtsgericht Dresden, HRB 31129.
> Geschäftsführer: Dr.-Ing. Michael Hohmuth
>
>
> _______________________________________________
> devel mailing list -- devel@uclibc-ng.org
> To unsubscribe send an email to devel-le...@uclibc-ng.org
_______________________________________________
devel mailing list -- devel@uclibc-ng.org
To unsubscribe send an email to devel-le...@uclibc-ng.org

Reply via email to