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

Alec Stewart alec-stewart at protonmail.com
Wed Feb 20 20:46:42 UTC 2019


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.


More information about the Digitalmars-d mailing list