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