Re: translate C struct char array into D

2021-08-02 Thread workman via Digitalmars-d-learn

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

2021-07-30 Thread russhy via Digitalmars-d-learn

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

2021-07-30 Thread jfondren via Digitalmars-d-learn

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

2021-07-30 Thread Paul Backus via Digitalmars-d-learn

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

2021-07-30 Thread H. S. Teoh via Digitalmars-d-learn
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

2021-07-30 Thread Tejas via Digitalmars-d-learn

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

2021-07-30 Thread Tejas via Digitalmars-d-learn

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

2021-07-30 Thread Paul Backus via Digitalmars-d-learn

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