# Assigning void returned from function?

**URL:** <https://ziggit.dev/t/assigning-void-returned-from-function/18043>\
**Category:** Explain\
**Tags:** language\
**Created:** [October 21, 2026, 1:14am UTC](https://ziggit.dev/t/assigning-void-returned-from-function/18043 "2026-10-21T01:14:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sinclairt](https://ziggit.dev/user_avatar/ziggit.dev/sinclairt/32/10347_2.png) [@sinclairt](https://ziggit.dev/u/sinclairt)\
**Post date:** [October 21, 2026, 1:14am UTC](https://ziggit.dev/t/assigning-void-returned-from-function/18043/1 "2026-10-21T01:14:54Z")

</div>

Why does this compile?

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

pub fn main() !void {
    const foo = std.debug.print("Hello, world\n", .{});
    _ = foo;
}

```

`std.debug.print()` returns `void`, but Zig doesn’t complain if I try to assign it to `foo`.

This came up for me in a project I’m working on, where I mistakenly assumed some API in a third-party lib was returning a value when in fact it wasn’t. I later triggered a compiler error by trying to format the returned value into a string with `{s}`, but it took me a while to work backward to the original mistake.

Are there cases where assigning `void` to a variable is useful?

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [October 21, 2026, 1:53am UTC](https://ziggit.dev/t/assigning-void-returned-from-function/18043/2 "2026-10-21T01:53:55Z")

</div>

It makes code where the value may or may not exist (determined at comptime) easier.

Instead of dissecting the function type, which may have layers of error unions to go through, its much easier to just check the type of the variable you assign it to.

And you might want to call the function regardless if it does other things.

There isn’t much harm in having an otherwise useless value.

---

<div class="post-metadata">

**Author:** ![zeeqeeng](https://ziggit.dev/letter_avatar_proxy/v4/letter/z/8baadc/32.png) [@zeeqeeng](https://ziggit.dev/u/zeeqeeng)\
**Post date:** [October 21, 2026, 1:54am UTC](https://ziggit.dev/t/assigning-void-returned-from-function/18043/3 "2026-10-21T01:54:45Z")

</div>

> The information is optional in the sense that not every expression has this information: assignment to `_`, for instance, does not provide any information about the type of an expression, nor does it provide a concrete memory location to place it in.

[Result Location Semantic](https://ziglang.org/documentation/master/#Result-Location-Semantics)

---

<div class="post-metadata">

**Author:** ![zeeqeeng](https://ziggit.dev/letter_avatar_proxy/v4/letter/z/8baadc/32.png) [@zeeqeeng](https://ziggit.dev/u/zeeqeeng)\
**Post date:** [October 21, 2026, 2:08am UTC](https://ziggit.dev/t/assigning-void-returned-from-function/18043/4 "2026-10-21T02:08:06Z")

</div>

I’m curious when and what “discarding”-s items should be put in a `test` block? For example the `std.zig` module has such code at the bottom of source code:

```zig
test {
    _ = Ast;
    _ = AstRlAnnotate;
    _ = BuiltinFn;
    _ = Client;
    _ = ErrorBundle;
    _ = LibCDirs;
    _ = LibCInstallation;
    _ = Server;
    _ = TokenSmith;
    _ = WindowsSdk;
    _ = number_literal;
    _ = primitives;
    _ = string_literal;
    _ = system;
    _ = target;
    _ = c_translation;
    _ = llvm;
    _ = @import("zig/parser_fuzz.zig");
}

```

Should I put all imported modules into that for a library? Or what modules should be done like that?

---

<div class="post-metadata">

**Author:** ![vulpesx](https://ziggit.dev/user_avatar/ziggit.dev/vulpesx/32/3989_2.png) [@vulpesx](https://ziggit.dev/u/vulpesx)\
**Post date:** [October 21, 2026, 2:17am UTC](https://ziggit.dev/t/assigning-void-returned-from-function/18043/5 "2026-10-21T02:17:45Z")

</div>

> [@zeeqeeng](#):
>
> Should I put all imported modules into that for a library? Or what modules should be done like that?

Only the root file will implicitly have its tests run, for other files/modules/namespaces you need to reference the namespace the tests are in. And this includes any `struct`/`union`/`enum` that has tests in that root file, they have to be referenced too.

And to be clear, `foo.bar` does not reference `foo`, only `foo.bar`, whereas `_ = foo` references `foo`.
