# Does the compiler know if a union field is never used?

**URL:** <https://ziggit.dev/t/does-the-compiler-know-if-a-union-field-is-never-used/5490>\
**Category:** Help\
**Tags:** language, compiler\
**Created:** [August 4, 2024, 4:49am UTC](https://ziggit.dev/t/does-the-compiler-know-if-a-union-field-is-never-used/5490 "2024-08-04T04:49:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nairou](https://ziggit.dev/user_avatar/ziggit.dev/nairou/32/3107_2.png) [@nairou](https://ziggit.dev/u/nairou)\
**Post date:** [August 4, 2024, 4:49am UTC](https://ziggit.dev/t/does-the-compiler-know-if-a-union-field-is-never-used/5490/1 "2024-08-04T04:49:13Z")

</div>

Let’s say you have a tagged union representing a list of platform-specific application backends:

```zig
const Backend = union(enum) {
    wayland: @import("wayland.zig"),
    x11: @import("x11.zig"),
    win32: @import("win32.zig"),
    cocoa: @import("cocoa.zig"),
    // etc.
}

```

The list is platform-specific, so on most (but not all) platforms only a single option will get set. Attempting to set the wrong field would result in a compile error, as it would import a file that uses external libraries that aren’t available on the target platform.

Is the compiler smart enough to know that a particular field is never used, and avoid importing that file? Or does the use of a union always imply that all code for all fields will get built?

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [August 4, 2024, 8:10am UTC](https://ziggit.dev/t/does-the-compiler-know-if-a-union-field-is-never-used/5490/2 "2024-08-04T08:10:57Z")

</div>

`@import` isn’t lazy. It always imports, regardless of where it’s declared, because it has to be evaluated at `comptime`.

Sidenote: the `path` argument has to be resolved even earlier, at “`parsetime`”, see [this topic](https://ziggit.dev/t/why-cant-import-take-a-string-literal-at-compile-time/3806).

---

<div class="post-metadata">

**Author:** ![nairou](https://ziggit.dev/user_avatar/ziggit.dev/nairou/32/3107_2.png) [@nairou](https://ziggit.dev/u/nairou)\
**Post date:** [August 4, 2024, 1:40pm UTC](https://ziggit.dev/t/does-the-compiler-know-if-a-union-field-is-never-used/5490/3 "2024-08-04T13:40:06Z")

</div>

> [@tensorush](#):
>
> `@import` isn’t lazy. It always imports, regardless of where it’s declared, because it has to be evaluated at `comptime`.

Very interesting, good to know!

So then, assuming all of the files get imported and comptime-resolved, and then the resulting structs go unused because no code ever references those structs (verifyable at comptime, such as `builtin.os.tag`), will they be discarded by the compiler?

I know unused functions are discarded, but I don’t know if unused union field structs are, or if the resulting binary will contain platform-specific function calls that will never get called on the target platform, but still had to be linked.

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [August 4, 2024, 2:02pm UTC](https://ziggit.dev/t/does-the-compiler-know-if-a-union-field-is-never-used/5490/4 "2024-08-04T14:02:39Z")

</div>

The file structs have to be semantically analyzed to determine the size of the union. I’m not so sure, but I think that in the case of switching on `builtin.os.tag` only the specific backend’s functions will be analyzed. However, in the case of static dispatch, i.e. when switching with `inline else`, functions from all backends will be analyzed.
