Disambiguate C headers where struct name = function name

This isn’t really a help post, just something I noticed which might help others. When importing a C header with a struct name that happens to be the same as a function name (stat.h, I am looking at you), then it’s an ambiguous situation and referencing it can cause an error, eg:

const cStat = @cImport(@cInclude("stat.h"));
.
.
.
var st = mem.zeroes(cStat.stat);; // Is it the struct stat or the function stat?

After studying the error output, I decided to try this:

var st = mem.zeroes(cStat.struct_stat);

And it worked. What sorcery is this?

Note that this isn’t necessary for unambiguous names. So both of these work:

_ = mem.zeroes(cStat.struct_timespec);
_ = mem.zeroes(cStat.timespec);

I haven’t seen this way to disambiguate struct names from function names documented anywhere, unless I missed something, so I thought I’d stick it here for Google to find in case someone else runs into this highly niche situation.

4 Likes

Thanks for sharing! I’m going to move this to the brainstorming category because I think it’s well suited for that.

I’d also suggest adding “Disambiguate” to the title so people can find it more easily :slight_smile:

I applied this change to master I think a few weeks ago. Previously, stat would have been defined twice here, so the @cImport would have just been an immediate compile error. Now, the alias const stat = struct_stat is only emitted if it doesn’t clash with any other identifier. If I remember right, struct_stat can itself be mangled if it clashes with a name, although then there’s no easy way to access the type.

I think it might be worth changing this again in future by namespacing all types under e.g. c.struct.stat or something like that (we can still keep the convenience aliases when they’re unambiguous!), but this namespacing issue will always exist in some way or another because C unavoidably does have separate namespaces for type names.

6 Likes

Ideally, code completion tools like ZLS could warn about this immediately and offer the updated struct_ prefixed name as a solution (or some other mangled name).

@AndrewCodeDev, I updated the title, thanks for the suggestion.