qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Better alternative to strncpy in QEMU.


From: Chetan
Subject: Re: Better alternative to strncpy in QEMU.
Date: Tue, 13 Apr 2021 08:20:34 +0530

Hello All,

> I'm not sure what's the improvement over strncpy() here? Paolo, could you
> elaborate?
> (Note that we also have some functions like strpadcpy() in QEMU already,
> which can be used in similar ways)

Ok Thanks, I'll wait for Paolo to clarify if the functions are needed, if yes then whether my understanding
is correct. If not, then I'll drop this and pick another one.

> Please use "*destination" and "*source" instead of "destination[]" and
> "source[]" here.

@Thomas Thanks for the input, I'll change it accordingly. 

> This implementation is "accidentally quadratic", because it
> calls strlen(source) every time through the loop, and thus
> copying an N byte string will read N*N bytes of memory. (The
> compiler can't pull the "strlen(source)" call up out of the loop
> because it can't guarantee that source and destination don't
> overlap.)

@Peter Thanks for the input, I'll be using a while loop instead, as Bruno suggested. Also, I will only continue with this task after Paolo's input.

> One other optimization that could be done (but is a bigger headache to implement correctly) would be to cast the char* into uint64_t* (or uint32_t* for 32-bit >systems) and copy more bytes at a time. The headache comes from finding a 0 in this longer variable, but you can probably use a similar strategy to freebsd's > strlen (https://github.com/freebsd/freebsd-src/blob/main/lib/libc/string/strlen.c).

@Bruno Thanks I'll check out freebsd code.

Thanks and Regards,
Chetan P.

On Mon, Apr 12, 2021 at 6:50 PM Peter Maydell <peter.maydell@linaro.org> wrote:
On Sun, 11 Apr 2021 at 14:52, Chetan <chetan4windows@gmail.com> wrote:
> char *qemu_strncpy(char destination[], char source[], size_t destination_size)
> {
>     /* Looping through the array and copying the characters from
>      * source to destination.
>      */
>     for (int i = 0; i < strlen(source); i++) {
>         destination[i] = source[i];
>
>         /* Check if value of i is equal to the second last index
>          * of destination array and if condition is true, mark last
>          * index as NULL and break from the loop.
>          */
>         if (i == (destination_size - 2)) {
>             destination[destination_size - 1] = '\0';
>             break;
>         }
>     }
>     return destination;
> }

This implementation is "accidentally quadratic", because it
calls strlen(source) every time through the loop, and thus
copying an N byte string will read N*N bytes of memory. (The
compiler can't pull the "strlen(source)" call up out of the loop
because it can't guarantee that source and destination don't
overlap.)

I think this is a good illustration of why we probably don't want
to roll our own string operation functions if we can avoid it
(ie without having a clear view of why we are improving on either
what libc or glib offer us).

thanks
-- PMM

reply via email to

[Prev in Thread] Current Thread [Next in Thread]