Re: translate C struct char array into D
On Friday, 30 July 2021 at 21:53:48 UTC, russhy wrote: On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: I get want to define this struct in D: ```c struct test1 { struct test1 *prev; struct test1 *next; size_t v1; size_t v2; size_t v3; char data[]; }; ``` ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char* data; }; ``` when I compare the size, test1.sizeof is 48 and sizeof(struct test1) from C is 40. Anyone can explain what should I do with this ? If I use test1 as member of other struct, the total size will not match. ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char[0] data; } ``` data.ptr to access its pointer Thanks for you all for the explain and tips, I will try avoid embed this struct into parent.
Re: translate C struct char array into D
On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: I get want to define this struct in D: ```c struct test1 { struct test1 *prev; struct test1 *next; size_t v1; size_t v2; size_t v3; char data[]; }; ``` ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char* data; }; ``` when I compare the size, test1.sizeof is 48 and sizeof(struct test1) from C is 40. Anyone can explain what should I do with this ? If I use test1 as member of other struct, the total size will not match. ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char[0] data; } ``` data.ptr to access its pointer
Re: translate C struct char array into D
On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: I get want to define this struct in D: ```c struct test1 { struct test1 *prev; struct test1 *next; size_t v1; size_t v2; size_t v3; char data[]; }; ``` The easy way: put a slice there instead of a fake array and accept that data's contents will be allocated separately. Slices will be more convenient to deal with in the language anyway. The C89 way: add a zero-length array and deal with its .ptr in appropriately sized allocations that you manage yourself (or get from a C API). A third way: something with https://dlang.org/phobos/core_lifetime.html#.emplace ```d import core.memory : pureMalloc, pureFree; import std.conv : to; struct Pascal { ubyte len; char[0] data; static Pascal* alloc(string s) { const len = s.length.to!ubyte; auto res = cast(Pascal*) pureMalloc(Pascal.sizeof + len); res.len = len; res.data.ptr[0 .. len] = s[0 .. len]; return res; } char[] toString()() { return data.ptr[0 .. len]; } } unittest { auto s = Pascal.alloc("hello"); scope (exit) pureFree(s); assert(s.toString == "hello"); assert((*s).sizeof == ubyte.sizeof); } ```
Re: translate C struct char array into D
On Friday, 30 July 2021 at 15:51:12 UTC, Tejas wrote: On Friday, 30 July 2021 at 14:40:17 UTC, Paul Backus wrote: On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: [...] `char data[]` in the C struct is not a pointer, but actually a [C99 flexible array member][1], and does not count towards the struct's `sizeof`. D does not have flexible array members, but you can simulate one using a struct method: ```d struct test1 { // member variables... char* data() { return cast(char*) ( + 1); } } ``` [1]: http://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16 By the way how is this safe? And how exactly are we even assigning the data to a variable/reference in this case? Can you please show an example demonstrating this? In order to use a flexible array member, you have to allocate extra memory beyond the end of the struct, and it's entirely your responsibility to ensure that you do not go out-of-bounds when accessing that memory.
Re: translate C struct char array into D
On Fri, Jul 30, 2021 at 03:41:32PM +, Tejas via Digitalmars-d-learn wrote: > On Friday, 30 July 2021 at 14:40:17 UTC, Paul Backus wrote: [...] > > ```d > > struct test1 { > > // member variables... > > > > char* data() { > > return cast(char*) ( + 1); > > } > > } > > ``` > > > > [1]: http://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16 > > B-but the performance penalty of having an extra level of indirection? > Absolutely unacceptable!! Premature optimization. Any optimizer worth its salt would be able to inline such a trivial function as .data above. Check the output of LDC -O, for example. (Don't talk to me about dmd, if you care about performance you'd use LDC instead.) T -- This is a tpyo.
Re: translate C struct char array into D
On Friday, 30 July 2021 at 14:40:17 UTC, Paul Backus wrote: On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: [...] `char data[]` in the C struct is not a pointer, but actually a [C99 flexible array member][1], and does not count towards the struct's `sizeof`. D does not have flexible array members, but you can simulate one using a struct method: ```d struct test1 { // member variables... char* data() { return cast(char*) ( + 1); } } ``` [1]: http://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16 By the way how is this safe? And how exactly are we even assigning the data to a variable/reference in this case? Can you please show an example demonstrating this?
Re: translate C struct char array into D
On Friday, 30 July 2021 at 14:40:17 UTC, Paul Backus wrote: On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: [...] `char data[]` in the C struct is not a pointer, but actually a [C99 flexible array member][1], and does not count towards the struct's `sizeof`. D does not have flexible array members, but you can simulate one using a struct method: ```d struct test1 { // member variables... char* data() { return cast(char*) ( + 1); } } ``` [1]: http://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16 B-but the performance penalty of having an extra level of indirection? Absolutely unacceptable!!
Re: translate C struct char array into D
On Friday, 30 July 2021 at 14:05:58 UTC, workman wrote: I get want to define this struct in D: ```c struct test1 { struct test1 *prev; struct test1 *next; size_t v1; size_t v2; size_t v3; char data[]; }; ``` ```d struct test1 { test1 *prev; test1 *next; size_t v1; size_t v2; size_t v3; char* data; }; ``` when I compare the size, test1.sizeof is 48 and sizeof(struct test1) from C is 40. Anyone can explain what should I do with this ? If I use test1 as member of other struct, the total size will not match. `char data[]` in the C struct is not a pointer, but actually a [C99 flexible array member][1], and does not count towards the struct's `sizeof`. D does not have flexible array members, but you can simulate one using a struct method: ```d struct test1 { // member variables... char* data() { return cast(char*) ( + 1); } } ``` [1]: http://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16