www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - need help to translate C into D

reply test123 <test123 gmail.com> writes:
I can not use importC, I need it to be work in D code.


```d
typedef struct {
   uint32_t mask_limit;   // Limit enum value that can be tested 
with mask.
   uint32_t value_count;  // Number of values after the bitfield.
   uint32_t data[];       // Bitmask + enumerated values follow.
} upb_MiniTable_Enum;
```

I am not sure how to define the `__gshared const 
upb_MiniTable_Enum` object for this struct.
Sep 12 2022
parent reply Marvin <thegrapevine email.com> writes:
On Tuesday, 13 September 2022 at 06:04:49 UTC, test123 wrote:
 I can not use importC, I need it to be work in D code.


 ```d
 typedef struct {
   uint32_t mask_limit;   // Limit enum value that can be tested 
 with mask.
   uint32_t value_count;  // Number of values after the bitfield.
   uint32_t data[];       // Bitmask + enumerated values follow.
 } upb_MiniTable_Enum;
 ```

 I am not sure how to define the `__gshared const 
 upb_MiniTable_Enum` object for this struct.
struct mystruct { uint32_t mask_limit; // Limit enum value that can be tested with mask. uint32_t value_count; // Number of values after the bitfield. uint32_t[] data; // Bitmask + enumerated values follow. } __gshared mystruct upb_MiniTable_Enum;
Sep 13 2022
parent reply test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 07:31:50 UTC, Marvin wrote:
 On Tuesday, 13 September 2022 at 06:04:49 UTC, test123 wrote:
 I can not use importC, I need it to be work in D code.


 ```d
 typedef struct {
   uint32_t mask_limit;   // Limit enum value that can be 
 tested with mask.
   uint32_t value_count;  // Number of values after the 
 bitfield.
   uint32_t data[];       // Bitmask + enumerated values follow.
 } upb_MiniTable_Enum;
 ```

 I am not sure how to define the `__gshared const 
 upb_MiniTable_Enum` object for this struct.
struct mystruct { uint32_t mask_limit; // Limit enum value that can be tested with mask. uint32_t value_count; // Number of values after the bitfield. uint32_t[] data; // Bitmask + enumerated values follow. } __gshared mystruct upb_MiniTable_Enum;
This will not work since the C have no array like D.
Sep 13 2022
parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 13 September 2022 at 09:43:46 UTC, test123 wrote:
 This will not work since the C have no array like D.
You can use a 0-size static array: ```D struct mystruct { uint32_t mask_limit; // Limit enum value that can be tested with mask. uint32_t value_count; // Number of values after the bitfield. uint32_t[0] data; // Bitmask + enumerated values follow. } ``` Then you have to index with `mystructVar.data.ptr[i]` to avoid bounds checking.
Sep 13 2022
parent reply test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 09:57:38 UTC, Dennis wrote:
 On Tuesday, 13 September 2022 at 09:43:46 UTC, test123 wrote:
 This will not work since the C have no array like D.
You can use a 0-size static array: ```D struct mystruct { uint32_t mask_limit; // Limit enum value that can be tested with mask. uint32_t value_count; // Number of values after the bitfield. uint32_t[0] data; // Bitmask + enumerated values follow. } ``` Then you have to index with `mystructVar.data.ptr[i]` to avoid bounds checking.
Thanks, this look nice. What I need is init the const object at CTFE. I try this way: ```d struct validate_KnownRegex_enum_init_type { const upb_MiniTable_Enum header; uint[2] data; } __gshared const validate_KnownRegex_enum_init_type validate_KnownRegex_enum_init = { {64, 2}, [7, 0] }; ``` The problem is I can not assign it into one array (give error): ```d __gshared const test = cast(upb_MiniTable_Enum*) &validate_KnownRegex_enum_init; __gshared const __enums_layout = [ test, ]; ``` This will also not work: ```d __gshared const upb_MiniTable_Enum*[1] __enums_layout = [ &validate_KnownRegex_enum_init.header, ]; ``` Is there a way to init the __gshared fixed length upb_MiniTable_Enum array ?
Sep 13 2022
next sibling parent test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 10:45:03 UTC, test123 wrote:
 upb_MiniTable_Enum array ?
2 type error I think it cloud be compiler bugs. 1): `expression `&validate_KnownRegex_enum_init_type(64u, 2u, [7u, 0u], ).header` is not a constant` ```d union validate_KnownRegex_enum_init_type { struct {uint a, b; uint[2] data;} upb_MiniTable_Enum header; } __gshared const validate_KnownRegex_enum_init_type validate_KnownRegex_enum_init = { 64, 2, [7, 0] }; __gshared const upb_MiniTable_Enum*[1] __enums_layout = [ &validate_KnownRegex_enum_init.header, ]; ``` 2:) `Error: reinterpreting cast from `const(validate_KnownRegex_enum_init_type)*` to `const(upb_MiniTable_Enum)*` is not supported in CTFE` ```d struct validate_KnownRegex_enum_init_type { uint a, b; uint[2] data;} __gshared const validate_KnownRegex_enum_init_type validate_KnownRegex_enum_init = { 64, 2, [7, 0] }; __gshared const upb_MiniTable_Enum*[1] __enums_layout = [ cast(const upb_MiniTable_Enum*) &validate_KnownRegex_enum_init, ]; ```
Sep 13 2022
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 13 September 2022 at 10:45:03 UTC, test123 wrote:
 Is there a way to init the __gshared fixed length 
 upb_MiniTable_Enum array ?
I don't think so. You could leave your array typed as `validate_KnownRegex_enum_init_type` and access it through a function that casts it to `upb_MiniTable_Enum`. Side node, you can use `immutable` instead of `__gshared const`, it amounts to the same for global variables.
Sep 13 2022
next sibling parent reply test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 10:59:36 UTC, Dennis wrote:
 On Tuesday, 13 September 2022 at 10:45:03 UTC, test123 wrote:
 Is there a way to init the __gshared fixed length 
 upb_MiniTable_Enum array ?
I don't think so. You could leave your array typed as `validate_KnownRegex_enum_init_type` and access it through a function that casts it to `upb_MiniTable_Enum`. Side node, you can use `immutable` instead of `__gshared const`, it amounts to the same for global variables.
I can not do this. because fixed sized array upb_MiniTable_Enum[] is passed into other const object. and upb_MiniTable_Enum can include a lot diff types. (for example mixed diff size upb_MiniTable_Enum)
Sep 13 2022
parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 13 September 2022 at 11:03:30 UTC, test123 wrote:
 and upb_MiniTable_Enum can include a lot diff types. (for 
 example mixed diff size upb_MiniTable_Enum)
I think you'll need a `void*` array then, since pointers to different structs can all implicitly convert to `void*`.
Sep 13 2022
parent test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 11:29:12 UTC, Dennis wrote:
 On Tuesday, 13 September 2022 at 11:03:30 UTC, test123 wrote:
 and upb_MiniTable_Enum can include a lot diff types. (for 
 example mixed diff size upb_MiniTable_Enum)
I think you'll need a `void*` array then, since pointers to different structs can all implicitly convert to `void*`.
Thanks for so much tips and help. I will try void*
Sep 13 2022
prev sibling next sibling parent test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 10:59:36 UTC, Dennis wrote:
 On Tuesday, 13 September 2022 at 10:45:03 UTC, test123 wrote:
 Is there a way to init the __gshared fixed length 
 upb_MiniTable_Enum array ?
I don't think so. You could leave your array typed as `validate_KnownRegex_enum_init_type` and access it through a function that casts it to `upb_MiniTable_Enum`. Side node, you can use `immutable` instead of `__gshared const`, it amounts to the same for global variables.
replace with immutable get this error: ```d static variable `__enums_layout` cannot be read at compile time ```
Sep 13 2022
prev sibling parent reply test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 10:59:36 UTC, Dennis wrote:
 On Tuesday, 13 September 2022 at 10:45:03 UTC, test123 wrote:
 Is there a way to init the __gshared fixed length 
 upb_MiniTable_Enum array ?
I don't think so. You could leave your array typed as `validate_KnownRegex_enum_init_type` and access it through a function that casts it to `upb_MiniTable_Enum`. Side node, you can use `immutable` instead of `__gshared const`, it amounts to the same for global variables.
because __enums_layout.ptr need to be part of other object, and this const ptr cloud be included in multi objects.
Sep 13 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 9/13/22 04:07, test123 wrote:
 On Tuesday, 13 September 2022 at 10:59:36 UTC, Dennis wrote:
 Side node, you can use `immutable` instead of `__gshared const`, it
 amounts to the same for global variables.
because __enums_layout.ptr need to be part of other object, and this const ptr cloud be included in multi objects.
There may be valid reasons not to use 'immutable' but you can still do what you describe. There is an 'immutable' array below and its .ptr is being stored as 'const' inside objects of another struct. struct S { int i; string s; int[3] arr; } immutable S[] imm; shared static this() { // Initializing immutable at program initialization time: imm ~= S(42, "hello", [1,2,3]); imm ~= S(7, "world", [4,5,6]); } struct Other { const S * ptr; } void main() { auto o = Other(imm.ptr); } That works because 'const' can point to 'immutable' (and mutable and const). Ali
Sep 13 2022
parent test123 <test123 gmail.com> writes:
On Tuesday, 13 September 2022 at 23:34:33 UTC, Ali Çehreli wrote:
 On 9/13/22 04:07, test123 wrote:
 On Tuesday, 13 September 2022 at 10:59:36 UTC, Dennis wrote:
 Side node, you can use `immutable` instead of `__gshared
const`, it
 amounts to the same for global variables.
because __enums_layout.ptr need to be part of other object,
and this
 const ptr cloud be included in multi objects.
There may be valid reasons not to use 'immutable' but you can still do what you describe. There is an 'immutable' array below and its .ptr is being stored as 'const' inside objects of another struct. struct S { int i; string s; int[3] arr; } immutable S[] imm; shared static this() { // Initializing immutable at program initialization time: imm ~= S(42, "hello", [1,2,3]); imm ~= S(7, "world", [4,5,6]); } struct Other { const S * ptr; } void main() { auto o = Other(imm.ptr); } That works because 'const' can point to 'immutable' (and mutable and const). Ali
Thanks for the tips. This is for a protobuf module and the `int[3] arr;` is variable, (diff size struct cloud in same group), and each struct is reused in multi part. (and the total number can be big depend on GRPC model) with `shared static this` the size is increased, and there is a lot depends relation need resolve during the protobuf init time. (the best solution is provide __gshared const relation map so no runtime cost, the C code way) What I can see, the best solution to fix this is allow take address of member `__gshared const struct` like this: ```d struct Header { int a; int b; } struct Message { Header header; uint[a] arr; } __gshared const Message type1 = {{1,2}, [3,4]}; __gshared const header_ptr = &type1.header; // then you can reuse header_ptr in multi other __gshared const ``` D dont need change to support `C struct array`, and all relation is const safe in memory. (not able to write into this section of memory) Current D support get `__gshared const struct` address, but not member of `__gshared const struct` address. if you do so it will throw error: ```sh expression &c(3u, 4u).a is not a constant ``` If you can `cast` the member address by the struct.offsetof, then this type error you get: ```sh Error: reinterpreting cast from `const(validate_KnownRegex_enum_init_type)*` to `const(upb_MiniTable_Enum)*` is not supported in CTFE ``` I can not think of the reason why prevent get const member address of `__gshared const struct`. and can not think of a workaround to bypass this problem.
Sep 13 2022