# What is useful about an empty enum value?

**URL:** <https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684>\
**Category:** Brainstorming\
**Tags:** language\
**Created:** [August 18, 2024, 11:23pm UTC](https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684 "2024-08-18T23:23:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sze](https://ziggit.dev/user_avatar/ziggit.dev/sze/32/496_2.png) [@Sze](https://ziggit.dev/u/Sze)\
**Post date:** [August 18, 2024, 11:23pm UTC](https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684/1 "2024-08-18T23:23:21Z")

</div>

> [@Creating an instance of enum{}](https://ziggit.dev/t/creating-an-instance-of-enum/5680):
>
> How do you make the following function compile? fn hello() enum {} { // ??? }

I am wondering when an empty enum is useful, it seems like it is a strange value for an enum, trying to print it gives me ‘cannot get `@tagName` of empty enum’, but `@comptimeLog` prints ‘(empty enum value)’.

Is empty enum allowed so that there is some kind of zero element, to simplify something about implementation, not having to special case?  
Does it have similarity to `u0`?

Are there other interesting properties about this value?

```zig
const std = @import("std");

pub fn main() !void {
    const val: enum {} = undefined;
    @compileLog(val);
    std.debug.print("val: {}\n", .{val});
}

```

---

<div class="post-metadata">

**Author:** ![squeek502](https://ziggit.dev/user_avatar/ziggit.dev/squeek502/32/409_2.png) [@squeek502](https://ziggit.dev/u/squeek502)\
**Post date:** [August 19, 2024, 8:40am UTC](https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684/2 "2024-08-19T08:40:42Z")

</div>

I’m not sure, but I did notice that there was a relevant proposal that was recently accepted:

> <https://github.com/ziglang/zig/issues/19855>
>
> Empty-AND-exhaustive \`enum\`-s are uninstantiable ("\`noreturn\`-like") types - see… #3257, #15909, and other issues for explanation.
> 
> In status-quo (tested \`0.13.0-dev.46+3648d7df1\`), the compiler chooses \`u0\` as the backing/tag type of \`enum{}\`.
> While that is not distinctly wrong, this is the same backing/tag type as chosen for an exhaustive \`enum\` with one value, \`enum{foo}\`.
> 
> Via manual override the compiler actually allows you to choose any integer type as the backing/tag of an uninstantiable \`enum\`.
> When using a non-zero-bit type, as fields they even participate in the size of the containing aggregate, even though they are uninstantiable,
> which I believe to be nonsensical behavior, and potentially a bit confusing:
> 
> \`\`\`zig
> pub const A = struct {
> bar: enum(u8){},
> };
> pub const B = packed union {
> foo: u8,
> bar: enum(u32){},
> };
> 
> comptime {
> const assert = @import("std").debug.assert;
> assert(@sizeOf(A) == 1); //uninstantiable type, so @sizeOf is not really meaningful
> assert(@sizeOf(B) == 4); //fits into a single byte, therefore could be argued that it should be 1 instead
> }
> \`\`\`
> 
> \*\*I propose\*\* that instead, \*\*an uninstantiable \`enum\` should always have a tag type of \`noreturn\`\*\*
> (whether explicitly specified or compiler-deduced),
> which should make its nature more clear to all parties.
> 
> When manually writing an uninstantiable \`enum\` type, the tag/backing type specified in status-quo is virtually meaningless.
> Still having an integer type specified may confuse readers -
> and the only reason I could think of doing this would be if the writer intended the \`enum\` with an instantiable backing/tag type to be instantiable.
> The proposal instead turns this into a compile error, clearly stating that the backing/tag type needs to change to \`noreturn\`, the enum needs at least one state/field, or to be made non-exhaustive.
> 
> As another small benefit, it becomes easier to account for the possibility of uninstantiable \`enum\` types in userland reflection code.
> Where today it might use the backing/tag 's bit size in calculation, like the compiler does in status-quo,
> \`noreturn\` isn't an integer type, so will trigger a compile error directly pointing to where logic needs to diverge.
> Code that deals with this in status-quo needs to special-case based on the enum having no fields AND being exhaustive,
> which is more complex and leads to less uniform code.
> 
> EDIT: Note that non-exhaustive \`enum\`-s already require specifying a backing/tag type in status-quo (f.e. \`enum{\_}\` leads to a compile error).
> Further, because \`\_\` already checks that there are unused state/field values left (\`enum(u1){a,b,\_}\` errors due to this),
> it seems the most regular to disallow \`enum(noreturn){\_}\` as well - there is no value for \`\_\` to represent.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [August 19, 2024, 4:00pm UTC](https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684/3 "2024-08-19T16:00:29Z")

</div>

I was looking for a return type that can be used to indicate that the caller doesn’t need to wait for the execution of a function to finish. If `enum{}` is going to get changed into `noreturn`, then I guess have to use `enum{no_wait}` instead.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://ziggit.dev/user_avatar/ziggit.dev/mnemnion/32/2478_2.png) [@mnemnion](https://ziggit.dev/u/mnemnion)\
**Post date:** [August 19, 2024, 7:48pm UTC](https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684/4 "2024-08-19T19:48:55Z")

</div>

That’s a better choice anyway. An enum of no types might work in a structurally-typed language, but in Zig one `enum {}` is different from the next `enum {}`, so it’s an awkward construct. Doing anything but comptime reflection with it is a compile error. Even if it was a singleton, there’s no justification for assigning the null enum to a particular role.

An enum inhabited by one tag, like `const NoWait = enum{no_wait};`, is backed by a `u0`, so it’s “free” in that sense, for whatever sort of metaprogramming you’re doing. The return instructions for the function should be the same as using `void` as a return value.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [August 19, 2024, 10:09pm UTC](https://ziggit.dev/t/what-is-useful-about-an-empty-enum-value/5684/5 "2024-08-19T22:09:00Z")

</div>

Yeah, it makes more sense semantically. More obvious what the declaration means than `enum{}`.

I’m working on adding support for function pointers to my project. The function being called would actually be a JavaScript function, which has to run in the main thread. When function is called from a different thread, I need to pause that thread and await the processing of the call. When the function isn’t actually returning a useful value, then that’s not really necessary. If the function is being called for logging purpose, for example.
