Best interface for memcpy() (and the string.h family of functions)

Stefanos Baziotis sdi1600105 at di.uoa.gr
Wed May 29 17:55:49 UTC 2019


On Wednesday, 29 May 2019 at 17:45:59 UTC, Jonathan Marler wrote:
>> I'm not sure about that. Does it really make sense to have 
>> such an
>> interface in the case where you don't have libc memcpy 
>> available?
>
> Sure.  Any time you have a buffer whose type isn't known at 
> compile-time and you need to copy between them.  For example, I 
> have an audio program that copies buffers of audio, but the 
> format of that buffer could be an array of floats or integers 
> depending on the format that your audio hardware and OS support.
>

So, you copy ubyte*.

>
> Well that's why you have memcpy (for those who know what 
> they're doing) and you have other functions for safe behavior.  
> But you don't want to instantiate a new version of memcpy for 
> every type variation, that's why they all just forward the call 
> to the real memcpy.
>

You want, because instantiation and inlining of specific types is
what makes D memcpy fast. And also, what I hope will make better 
error
messages and instrumentation. But that's yet to be seen, most 
important
is the performance.

>
> Yes it could be done, but then you end up with N copies of your 
> memcpy implementation, one for every combination of types.  
> You're code size is going to explode.  You can certainly 
> support the signature you provided, I just wouldn't have the 
> implementation inside of that template, instead you should cast 
> and forward to memcpy.
>

Actually, code size for arrays is a very good reminder, thanks.

>> The thing with all this code depending on libc memcpy is that 
>> to my understanding,
>> the prospect is that libc will be removed. And this project is 
>> a step towards that
>> by making some better D versions (meaning, leveraging D 
>> features).
>
> Right, which is why you use the libc version by default, and 
> only use your own when libc is disabled.  This is what I do in 
> my standard library https://github.com/marler8997/mar which 
> works with or without libc.  I went through several designs for 
> how to go about this memcpy solution and what I've provided you 
> is the result of that.
>
>> If the better version calls libc, then when libc
>> is finally removed, all this code will break. And because we 
>> encouraged
>> this bad practice, _a lot_ of code will break.
>
> How would it break?  If you remove libc, your module should now 
> enable your implementation of memcpy.  And all the code that 
> calls memcpy doesn't care whether it came from libc or from a D 
> module.

My point is that you will write code differently depending on 
what memcpy
you have, that's why this "new memcpy" will have different 
signature. To have
the best of both worlds, we would have to write our own
memcpy(void*, void*, size_t);.
And so, if you encourage the use of this interface (because hey, 
even if you don't
have libc eventually, your code will not crash), when libc is not 
present,
the code will be slow.


More information about the Digitalmars-d mailing list