Request assistance initializing struct instance at global scope

Adam D. Ruppe destructionator at gmail.com
Mon Dec 7 13:56:15 UTC 2020


On Monday, 7 December 2020 at 04:13:16 UTC, Andrew Edwards wrote:
> Given:
>
> ===============
> extern(C):
> char*[] hldr;

Why is this extern(C)? A D array ere is probably wrong.

In C, a `char*[] hldr = {...}` is actually represented in D as a 
static length array, like `char*[1] = [null];`

It should also generally be __gshared if it was declared in C (C 
defaults to global, D defaults to thread-local), and if declared 
in C, an additional extern may be required.


So, if you are trying to *link* to C code that has this:

---
// C
char* hldr[] = {0};
---

You'd bind to it in D with

---
// D
extern(C) extern __gshared char*[1] hldr; // matches the C. Make 
sure the length matches too

// rest for your code the same:
enum I = (1<<0);
struct S { char* ft; char** fm; int f; }

S[] s = [S(cast(char*) "c", &hldr[0])]; // that cast is super 
iffy though. Should S have `const(char)* ft` instead?

void main(){}
---


In that thing:

extern(C) - tells it it has a C name.
extern - tells it the actual variable is declared externally. 
This second one makes the linker pull the variable's address from 
the C code instead of declaring a new variable in D that can be 
used from C.
__gshared - turn off D's thread local default to match C's global.



Now if you are translating C code to D, that might be different, 
certainly the second extern is wrong then, and you need to copy 
over the initial value but the rest still works:

```
// no more second extern, D is now creating a new variable, then 
it needs to know the value too
extern(C) __gshared char*[1] hldr = [null];

// rest is the same
// including
S[] s = [S(cast(char*) "c", &hldr[0])]; // since it is a gshared 
static array, this still works
```



But there's a few other contexts that might change this, then you 
probably do want the static constructor, or maybe you can make 
some things immutable and make it work that way. All depends on a 
bit more information than your code gives on its own....


More information about the Digitalmars-d-learn mailing list