link errors when using extern (C) structs

Nicholas Wilson iamthewilsonator at hotmail.com
Sun Oct 28 03:39:41 UTC 2018


On Sunday, 28 October 2018 at 03:28:20 UTC, DanielG wrote:
> I'm wrapping a C library which has a lot of structs defined, 
> and I keep running into issues where dmd complains that .init 
> isn't defined ("Symbol Undefined __xxxxxxx__initZ" etc).
>
> I'm struggling to narrow it down to a simple example that 
> demonstrates it - I actually made something that's kind of 
> minimal, but it goes from working to breaking depending on 
> whether the file extension is .di or .d, for the file 
> containing the extern (C)'ed struct definitions. Also it seems 
> to depend (in the .di case) on whether the C structs use double 
> vs. int values for their fields. (int fields work with either 
> file extension)

That is because the default initialiser for double is double.nan 
which is non-zero and therefore the default initialiser of a 
struct containing a double will have a non-zero default 
initialiser. This lives as a  __xxxxxxx__initZ symbol somewhere 
in your program.

The .di or .d is because in the case of .di the compiler assumes 
the symbols exist somewhere already and it doesn't need to (and 
can't because it would create duplicates) emit them to the object 
files.

> But simply changing the file extension in my real project, of 
> the header files translated by dstep, seems to have no effect.
>
> In short, it seems that for certain C structs I cannot use them 
> as a field in a D struct even with a manually-specified default 
> value - I get link errors no matter what 
> (init/toHash/opEquals). How can I get around that?
>
> Am I supposed to be doing something with C structs to avoid 
> these kinds of errors in my D code? I've searched the forum but 
> nothing really jumps out at me as relevant.

For the __initZ symbols

struct Foo {
     double bar;
}

write struct Foo {
     double bar = 0.0; // The bitpattern of 0.0 is 0
}

and have only zero initialiser for you structs, which means they 
don't need to be stored.

the opEquals stems from the fact that for structs containing 
floats equality comparison cannot be implemented with bitwise 
compare.

The easiest solution is to just use .d for the extension, very 
rarely are .di files useful.


More information about the Digitalmars-d-learn mailing list