public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx.manpages@gmail.com>
To: Noah Goldstein <goldstein.w.n@gmail.com>
Cc: Wilco Dijkstra <Wilco.Dijkstra@arm.com>,
	GNU C Library <libc-alpha@sourceware.org>
Subject: Re: [PATCH 1/1] string: Add stpecpy(3)
Date: Sun, 25 Dec 2022 15:37:38 +0100	[thread overview]
Message-ID: <703b1fca-27ae-d1c7-863b-0573296fdb43@gmail.com> (raw)
In-Reply-To: <CAFUsyfJ9G_HjmZJJORv7ES02dmDF1Rc7tG=wVYwwBTbOmX5FUA@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 3160 bytes --]

Hi Noah,

On 12/25/22 02:52, Noah Goldstein wrote:

>> char *
>> stpecpy (char *dst, char *end, const char *restrict src)
>> {
>>     size_t dsize;
>>     size_t dlen;
>>     size_t slen = strlen (src);
> 
> Imo move `dst == end` and `dst == NULL` check before strlen


That's a valid optimization.  Having strlen(3) before has the advantage that you 
make sure that your strings are strings, as strlcpy(3) does.  But since we're 
inventing stpecpy(3), we can choose to be faster.  If anyone wants to instrument 
their code, they can add a temporary wrapper that does that.

> and change strlen to `strnlen(src, dsize)`.

About strnlen(3), I have doubts.  Isn't strlen(3) faster for the common case of 
no truncation or little truncation?  strnlen(3) would optimize for the case 
where you truncate by a large difference.

>>     bool   trunc = false;
>>
>>     if (dst == end)
> 
> Out of curiosity what if `end < dst`?

The behavior is undefined.  That's by design.  In the definition of stpecpy(3) I 
have currently in libstp, I even tell the compiler to optimize on that condition:
<http://www.alejandro-colomar.es/src/alx/alx/libstp.git/tree/include/stp/stpe/stpecpy.h#n33>


alx@asus5775:~/src/alx/libstp$ grepc -tfd stpecpy
./include/stp/stpe/stpecpy.h:21:
inline char *stp_nullable
stpecpy(char *stp_nullable dst, char *end, const char *restrict src)
{
	bool    trunc;
	size_t  dsize, dlen, slen;

	slen = strlen(src);

	if (dst == end)
		return end;
	if (stp_unlikely(dst == NULL))  // Allow chaining with stpeprintf().
		return NULL;
	stp_impossible(dst > end);

	dsize = end - dst;
	trunc = (slen >= dsize);
	dlen = trunc ? dsize - 1 : slen;
	dst[dlen] = '\0';

	return mempcpy(dst, src, dlen) + trunc;
}
alx@asus5775:~/src/alx/libstp$ grepc -tm stp_impossible
./include/stp/_compiler.h:14:
#define stp_impossible(e)   do                                                \
{                                                                             \
	if (e)                                                                \
		stp_unreachable();                                            \
} while (0)
alx@asus5775:~/src/alx/libstp$ grep -rnC1 define.stp_unreachable
include/stp/_compiler.h-28-#if defined(unreachable)
include/stp/_compiler.h:29:# define stp_unreachable()  unreachable()
include/stp/_compiler.h-30-#else
include/stp/_compiler.h:31:# define stp_unreachable()  __builtin_unreachable()
include/stp/_compiler.h-32-#endif


I'd do that for glibc, but I don't see any facility.  Maybe we should add an 
__impossible() macro to document UB, and help the compiler.

Cheers,

Alex

>>       return NULL;
>>     if (dst == NULL)
>>       return NULL;
>>     dsize = end - dst;
>>     trunc = (slen >= dsize);
>>     dlen = trunc ? dsize - 1 : slen;
>>     dst[dlen] = 0;
>>     return mempcpy(dst, src, dlen) + trunc;
>> }
>>
>> This adds a '+' operation, so the difference compared to your strlcpy(3) is
>> smaller, but stpecpy() still wins, I think.
>>
>>
>> --
>> <http://www.alejandro-colomar.es/>

-- 
<http://www.alejandro-colomar.es/>

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2022-12-25 14:37 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-23 23:24 Wilco Dijkstra
2022-12-24  0:05 ` Alejandro Colomar
2022-12-24  0:26   ` Alejandro Colomar
2022-12-24  2:30     ` stpecpy(3) vs strlcpy(3) benchmark (was: [PATCH 1/1] string: Add stpecpy(3)) Alejandro Colomar
2022-12-24 10:28       ` Alejandro Colomar
2022-12-25  1:52     ` [PATCH 1/1] string: Add stpecpy(3) Noah Goldstein
2022-12-25 14:37       ` Alejandro Colomar [this message]
2022-12-25 22:31         ` Noah Goldstein
2022-12-26  0:26           ` Alejandro Colomar
2022-12-26  0:32             ` Noah Goldstein
2022-12-26  0:37               ` Alejandro Colomar
2022-12-26  2:43                 ` Noah Goldstein
2022-12-26 22:25                   ` Alejandro Colomar
2022-12-26 23:24                     ` Alejandro Colomar
2022-12-26 23:52                       ` Alejandro Colomar
2022-12-27  0:12                         ` Alejandro Colomar
  -- strict thread matches above, loose matches on Subject: below --
2022-12-23 18:35 Wilco Dijkstra
2022-12-23 22:40 ` Alejandro Colomar
2022-12-23 14:59 Wilco Dijkstra
2022-12-23 17:03 ` Alejandro Colomar
2022-12-23 17:27   ` Alejandro Colomar
2022-12-22 21:42 [PATCH 0/1] " Alejandro Colomar
2022-12-22 21:42 ` [PATCH 1/1] " Alejandro Colomar
2022-12-23  7:02   ` Sam James
2022-12-23 12:26     ` Alejandro Colomar
2022-12-23 12:29       ` Alejandro Colomar
2022-12-23 17:21       ` Alejandro Colomar
2022-12-31 15:13       ` Sam James
2022-12-31 15:15         ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=703b1fca-27ae-d1c7-863b-0573296fdb43@gmail.com \
    --to=alx.manpages@gmail.com \
    --cc=Wilco.Dijkstra@arm.com \
    --cc=goldstein.w.n@gmail.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).