Thread overview
From C to D: issue with arguments for core.stdc.string.memcpy
Feb 22
Meta
February 20
So I've been close to translating a small single header C library to D for a bit now, and I'm just going to admit that I am no expert in C or D. The exact error I'm getting is

    ... cannot pass argument `(s*).stack.buffer` of type `char[31]`  to parameter `return scope void s1`

Now here's the relevant D code:


    static auto RS_ALIGNMENT() {
        return (void *).sizeof > size_t.sizeof ? (void *).sizeof : size_t.sizeof;
    }

    struct rs_heap
    {
        char* buffer;

        size_t size;

        size_t capacity;

        ubyte[RS_ALIGNMENT - 1] align_;

        ubyte flag;
    }

    enum RS_STACK_CAPACITY = rs_heap.sizeof - 1;


    struct rs_stack
    {

        char[RS_STACK_CAPACITY] buffer;

        ubyte left;
    }

    union rapidstring
    {
        rs_stack stack;

        rs_heap heap;
    }

and what I'm trying to do is

    memcpy(s.stack.buffer, input, n);
    // s is of type rapidstring*
    // input is of type const(char)*
    // and n is size_t


Here's the relevant C code

    #ifndef RS_STACK_CAPACITY
    #define RS_STACK_CAPACITY (sizeof(rs_heap) - 1)
    #endif

    #ifdef RS_STACK_CAPACITY
    #define RS_ALIGNMENT \
	(sizeof(void *) > sizeof(size_t) ? sizeof(void *) : sizeof(size_t))
    #endif

    typedef struct {
	
	char *buffer;

	size_t size;
	
	size_t capacity;

	unsigned char align[RS_ALIGNMENT - 1];
	
	unsigned char flag;
    } rs_heap;

    typedef struct {
	
	char buffer[RS_STACK_CAPACITY];
	
        unsigned char left;
    } rs_stack;

    typedef union {

	rs_stack stack;

	rs_heap heap;
    } rapidstring;

(here's the library I'm translating: https://github.com/boyerjohn/rapidstring)


BUT while in C `memcpy(s->stack.buffer, input, n);` doesn't throw any linter/checker errors (in my editor or on https://repl.it/languages/C), it will return an exit status of -1 (on https://repl.it/languages/C at least) when just testing with

    int main(void) {
      rapidstring* s;
      const char * input;
      size_t n;
      memcpy(s->stack.buffer, input, n);
      printf("Will print if we don't get an exit status of -1");
      return 0;
    }


But thankfully, the Online D Editor actually gives an error when trying


    void main()
    {
        rapidstring* s;
        const(char)* input;
        size_t n;

        import core.stdc.string : memcpy;
        memcpy(s.stack.buffer, input, n);
        import std.stdio : writeln;
        writeln("prints if we don't fail");
    }

The error

    onlineapp.d(42): Error: function core.stdc.string.memcpy(return scope void* s1, scope const(void*) s2, ulong n) is not callable using argument types (char[31], const(char)*, ulong)
    onlineapp.d(42):        cannot pass argument (*s).stack.buffer of type char[31] to parameter return scope void* s1


SO, with all of that; how can I fix this? Do I have to do some ugly type casting?

Sorry if it's a really stupid question.
February 20
On Wednesday, 20 February 2019 at 20:46:42 UTC, Alec Stewart wrote:

>
> The error
>
>     onlineapp.d(42): Error: function core.stdc.string.memcpy(return scope void* s1, scope const(void*) s2, ulong n) is not callable using argument types (char[31], const(char)*, ulong)
>     onlineapp.d(42):        cannot pass argument (*s).stack.buffer of type char[31] to parameter return scope void* s1
>
>
> SO, with all of that; how can I fix this? Do I have to do some ugly type casting?
>

You're passing a static array where the function expects a pointer.

memcpy(s.stack.buffer.ptr, input, n);
February 22
On Wednesday, 20 February 2019 at 20:57:26 UTC, Mike Parker wrote:
> On Wednesday, 20 February 2019 at 20:46:42 UTC, Alec Stewart wrote:
>
>>
>> The error
>>
>>     onlineapp.d(42): Error: function core.stdc.string.memcpy(return scope void* s1, scope const(void*) s2, ulong n) is not callable using argument types (char[31], const(char)*, ulong)
>>     onlineapp.d(42):        cannot pass argument (*s).stack.buffer of type char[31] to parameter return scope void* s1
>>
>>
>> SO, with all of that; how can I fix this? Do I have to do some ugly type casting?
>>
>
> You're passing a static array where the function expects a pointer.
>
> memcpy(s.stack.buffer.ptr, input, n);

To expand on this just a bit, in case you're not familiar with D, arrays in D do not decay to a pointer like they do in C. You need to pass s.stack.buffer.ptr instead.
February 22
On Friday, 22 February 2019 at 16:38:10 UTC, Meta wrote:
> On Wednesday, 20 February 2019 at 20:57:26 UTC, Mike Parker wrote:
>> On Wednesday, 20 February 2019 at 20:46:42 UTC, Alec Stewart wrote:
>>
>>>[...]
>>
>> You're passing a static array where the function expects a pointer.
>>
>> memcpy(s.stack.buffer.ptr, input, n);
>
> To expand on this just a bit, in case you're not familiar with D, arrays in D do not decay to a pointer like they do in C. You need to pass s.stack.buffer.ptr instead.

Ah, that makes sense! Thank you all!