Re: [PATCH] libbb/last_char_is: rewrite for smaller and faster code

2020-07-04 Thread Kang-Che Sung
On Saturday, July 4, 2020, Harald van Dijk  wrote:
>
> This is really the same problem as with standard library functions such
as strchr(). The function should have a return type of char* if its
argument has type char*. The function should have a return type of const
char* if its argument has type const char*. The current signature is the
only signature that allows all code that should be valid, at the expense of
not rejecting code that should be invalid.

Just to give a note: The const-correctness problem could have been avoided
if the function API returns an offset (of `size_t` type) rather than the
pointer directly. But it may be too late for the standard library to
correct this historical mistake.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] libbb/last_char_is: rewrite for smaller and faster code

2020-07-04 Thread Harald van Dijk

On 04/07/2020 09:56, Emmanuel Deloget wrote:

On Fri, Jul 3, 2020 at 9:15 PM Tito  wrote:

On 7/3/20 6:13 PM, Xabier Oneca -- xOneca wrote:

Also, there's a warning compiling this function: return discards
‘const’ qualifier from pointer target type


Hi,
cast it?

char* FAST_FUNC last_char_is(const char *s, int c)
{
  if (!s || !*s) return NULL;
  while (*(++s));
  return (*(--s) == c) ? (char *)s : NULL;
}



In favor of const-correctness, wouldn't it be better to return a const
char*? It's quite strange to promote a string to const and to a part
of it that is non-const (not to mention that if you feed the function
with a real const char* then the cast is not a good thing to do).


Existing callers rely on the return type being char*.

This is really the same problem as with standard library functions such 
as strchr(). The function should have a return type of char* if its 
argument has type char*. The function should have a return type of const 
char* if its argument has type const char*. The current signature is the 
only signature that allows all code that should be valid, at the expense 
of not rejecting code that should be invalid.


busybox could define last_char_is as a macro that wraps this function, 
which would optionally cast the return value to const char*. Such a 
macro would be easy to define using _Generic, assuming the compiler is 
recent enough to support it. This would ensure all code that should be 
valid remains valid, while some (not all) code that should not be valid 
becomes invalid. Such a macro could look like


#define last_char_is(s, c)   \
  (_Generic((s), \
const char *: (const char *) (last_char_is) ((s), (c)),  \
default: (last_char_is) ((s), (c

But considering busybox uses standard library functions with the same 
problem throughout the codebase, fixing it just for last_char_is while 
leaving alone all other functions may not be worth the effort.


Cheers,
Harald van Dijk
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] libbb/last_char_is: rewrite for smaller and faster code

2020-07-04 Thread Emmanuel Deloget
Hello,

On Fri, Jul 3, 2020 at 9:15 PM Tito  wrote:
>
>
>
> On 7/3/20 6:13 PM, Xabier Oneca -- xOneca wrote:
> > Hi all,
> >
> >>> On Fri, 2020-07-03 at 08:12 +0200, Tito wrote:
> >>> [...]
>  Improved version:
> 
>  char* last_char_is(const char *s, int c)  {
>   if (!s || !*s) return NULL;
>   while (*(s + 1))s++;
>   return (c == *s) ? (char *)s : NULL;
>  }
> >
> > Let me "improve" the Tito's -11 bytes, probably introducing some subtle bug 
> > :)
> >
> > char* FAST_FUNC last_char_is(const char *s, int c)
> > {
> > if (!s || !*s) return NULL;
> > while (*(++s));
> > return (*(--s) == c) ? s : NULL;
> > }
> >
> > function old new   delta
> > last_char_is  58  42 -16
> > --
> > (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-16) Total: -16 
> > bytes
> >textdata bss dec hex filename
> >  95644942351904  962588   eb01c busybox_old
> >  95643342351904  962572   eb00c busybox_unstripped
> >
> > Also, there's a warning compiling this function: return discards
> > ‘const’ qualifier from pointer target type
>
> Hi,
> cast it?
>
> char* FAST_FUNC last_char_is(const char *s, int c)
> {
>  if (!s || !*s) return NULL;
>  while (*(++s));
>  return (*(--s) == c) ? (char *)s : NULL;
> }
>

In favor of const-correctness, wouldn't it be better to return a const
char*? It's quite strange to promote a string to const and to a part
of it that is non-const (not to mention that if you feed the function
with a real const char* then the cast is not a good thing to do).

>
> > Fun to play with you.
> >
> > Cheers,
> >
> > Xabier Oneca_,,_

Best regards,

-- Emmanuel Deloget
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox