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