@cImport/@cInclude Produces Multiple Constants of the Same Struct

When using @cImport(@cInclude("some_file.h")) I’m getting multiple definitions of the same struct depending on how I declare it. I ran a search for @cImport through the github issues, but I didn’t see an issue relating to this (maybe I missed it?).

For reference, I am using ZLS.

Here’s an example header (we’ll call it head.h):

struct c32 { float r; float i; };

If I now include this like so…

const decls = @cImport(
    @cInclude("path/to/head.h")
);

I see two constants:

decls.struct_c32
decls.c32

But if I declare c32 in head.h like so…

typedef struct { float r; float i; } c32;

After reloading my Helix editor, I only get:

decls.c32

So I’m of course curious - is this an issue with how Zig imports C files, or is this a ZLS issue? I’m leaning towards just using typedef to cut down on the white noise.

Thanks :slight_smile:

I can’t find the commit/discussion on GitHub but I know I’ve read this somewhere: translate-c defines the struct_name constants for the C struct namespace, and then it also defines aliases without the struct_ prefix if they won’t cause a name conflict.

4 Likes

Interesting - thanks for the info. It’s interesting that the typedef gets around this, but it is a form of alias (so maybe that actually makes sense).

In the case of typedef struct { } mystruct the struct type is anonymous, so there is no struct mystruct in the C struct namespace.

1 Like

I sometimes do something like

struct some_struct {
} typedef SomeStruct;

and then use either struct some_struct *s/s or SomeStruct *s/s.

1 Like

Hmm… but I can’t remember for the life of me where I learned that form of typedef with structs (as opposed to “canonical” typedef <existing-type> <alias>) from :frowning: