www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - From C to D: issue with arguments for core.stdc.string.memcpy

reply Alec Stewart <alec-stewart protonmail.com> writes:
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.
Feb 20 2019
parent reply Mike Parker <aldacron gmail.com> writes:
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);
Feb 20 2019
parent reply Meta <jared771 gmail.com> writes:
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.
Feb 22 2019
parent Alec Stewart <alec-stewart protonmail.com> writes:
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!
Feb 22 2019