# Error: local variable is never mutated

**URL:** <https://ziggit.dev/t/error-local-variable-is-never-mutated/2238>\
**Category:** News\
**Tags:** language, compiler\
**Created:** [November 21, 2023, 7:38am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238 "2023-11-21T07:38:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 7:38am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/1 "2023-11-21T07:38:46Z")

</div>

Just a heads up: today’s fresh dev build of Zig 0.12 (0.12.0-dev.1664+8ca4a5240) introduced this requirement where you must declare your `var` a `const` if you never modify it.

An example:

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

pub fn main() void
{
    var a: u32 = 0;
    std.debug.print("a = {}\n", .{a});
}

```

The error:

```zig
$ zig run var_not_mutated.zig 
var_not_mutated:5:9: error: local variable is never mutated
    var a: u32 = 0;
        ^
var_not_mutated:5:9: note: consider using 'const'

```

Some may not like it, just as some complain about unused variable / constant being an error, but I think this is a [Good Thing](https://www.catb.org/jargon/html/G/Good-Thing.html)™.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [November 21, 2023, 7:49am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/2 "2023-11-21T07:49:24Z")

</div>

I agree with your sentiment. Const should really be the go to unless you plan on changing something. It makes longer code examples easier to read (I read a lot of convoluted error handling code at work and one of the best ways to clean it up is to declare existing stuff as const… immediately tells you what’s actually being changed).

---

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 7:56am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/3 "2023-11-21T07:56:21Z")

</div>

Indeed. I have noticed I do have several example programs in [my Zig port of some of raylib examples](https://github.com/Durobot/raylib-zig-examples) (shameless plug) that now produce this error as I was testing them with a new dev build of Zig.

I’m happy Zig compiler now points out the places where I could (and now, must) use `const` instead of `var`. Thumbs up!

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [November 21, 2023, 8:43am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/4 "2023-11-21T08:43:24Z")

</div>

It is fantastic that we get this help from the compiler to catch “sloppy” code.

But I also wish I could tell the compiler to let the sloppy code be “for now”. For example, when I am making quick changes and prototyping. I don’t mind being reminded I should clean it up at some point; I wish I could tell the compiler to “leave me alone” for now.

To potential repliers: please don’t cast this into a discussion about this sort of error being bad. I _love_ having these errors. All I am saying is, I wish I could quiet them down while I am exploring my alternatives.

---

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 8:45am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/5 "2023-11-21T08:45:51Z")

</div>

I understand what you’re saying… but I’m fearful that this “for now” switch can become permanent in some projects. You know what they say, there’s nothing more permanent than temporary solutions.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [November 21, 2023, 8:59am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/6 "2023-11-21T08:59:07Z")

</div>

Your point about exploration is really interesting and it got me to thinking more about what this change implies.

It does make new users pay a heavier upfront fee in required learning… ya know, “don’t do x because x won’t compile due to y”. On the whole, I think this is a good change, but too much of it can quickly become constricting and incentivize people to do exploration elsewhere (like writing drafts in python instead of directly using the intended language itself).

There’s a fine line here. Back in ye olden times, programs could just stomp on the memory of another process. Sure, you had more freedom, but that also meant you had all the consequences of that freedom. Some people actually dislike type explicit languages entirely for this reason (it supposedly inhibits them from trying things).

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [November 21, 2023, 9:32am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/7 "2023-11-21T09:32:33Z")

</div>

I remember times when I have wanted to explore what I call “stupid changes” in my codebase – turn a whole thing off (which I know will break the algorithms) just to see if the impact on performance, or some other effect, is what I think it is. I usually do this in C with `#if 0` / `#endif` blocks, which nest nicely. The point is, I _know_ this is not the state of the code I want; I just want to see what happens. This is what I referred to as “exploration” above.

With this change (and related features, such as flagging parameters / variables when they are unused), and without the possibility of turning on this “sloppy mode” (temporarily making these errors into warnings, or hiding them), I find that sometimes this type of change percolates into a chain of useless changes, just because I wanted to see “what happens if…”.

Cheers!

---

<div class="post-metadata">

**Author:** ![bmacho](https://ziggit.dev/user_avatar/ziggit.dev/bmacho/32/641_2.png) [@bmacho](https://ziggit.dev/u/bmacho)\
**Post date:** [November 21, 2023, 9:33am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/8 "2023-11-21T09:33:04Z")

</div>

> [@Durobot](#):
>
> I understand what you’re saying… but I’m fearful that this “for now” switch can become permanent in some projects. You know what they say, there’s nothing more permanent than temporary solutions.

If it is a warning, and a simple formatter can fix it, I don’t see how could that happen, or be a problem.

A big and fundamental project refuse to apply the formatter to delete unused variables and to turn the unmutated variables constant? Doesn’t seem likely to me.

Actively not letting people to prototype and refactor and experiment with code is a direct problem however.

---

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 9:39am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/9 "2023-11-21T09:39:48Z")

</div>

> [@bmacho](#):
>
> Actively not letting people to prototype and refactor and experiment with code is a direct problem however.

Having to change `var` to `const` and vice versa periodically, or add / remove `_ = my_var;` in prototype code you constantly edit anyway… I don’t know, doesn’t look like a big deal IMHO.

---

<div class="post-metadata">

**Author:** ![slonik-az](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@slonik-az](https://ziggit.dev/u/slonik-az)\
**Post date:** [November 21, 2023, 9:53am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/10 "2023-11-21T09:53:07Z")

</div>

> [@gonzo](#):
>
> But I also wish I could tell the compiler to let the sloppy code be “for now”

Oh no! In coding “for now” is a synonym for “forever”.

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [November 21, 2023, 10:11am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/11 "2023-11-21T10:11:15Z")

</div>

I simply disagree. I would like to have this available in my toolchain.

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [November 21, 2023, 10:15am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/12 "2023-11-21T10:15:25Z")

</div>

One way of doing this would be adding a flag `--sane` or `--strict` that will not give you any room for shenanigans – error out on all unused parameters / variables, on `var`s that should be `const`s, etc. Maybe even let this be the default configuration, but _have_ a way to turn it off.

From past discussions, it certainly seems that this will not happen. Oh well.

---

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 10:45am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/13 "2023-11-21T10:45:32Z")

</div>

I’m afraid such a flag would be abused. The only mitigation I could think of is for the compiler to ask for a time-limited token, a-la Github personal access tokens, with this flag. But then again people would just write scripts and automate token generation and it’s not going to help at all…

---

<div class="post-metadata">

**Author:** ![gonzo](https://ziggit.dev/user_avatar/ziggit.dev/gonzo/32/54_2.png) [@gonzo](https://ziggit.dev/u/gonzo)\
**Post date:** [November 21, 2023, 10:54am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/14 "2023-11-21T10:54:06Z")

</div>

I think we have different definitions / expectations of “abuse”, and how far the tooling should go to “protect from” / disable unwanted behaviour. If `zig foo bar` errors out on any of the things we have discussed here, how can it be abused? In this case, I am forced to write `zig --sloppy foo bar` if I want to opt into the sloppy mode.

---

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 11:02am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/15 "2023-11-21T11:02:50Z")

</div>

The thing I am worried about is not somebody having an option to disable guardrails while playing in his/her sandbox, but that this option is going to be (ab)used “in production environment”. E.g. “we need this feature last week, no time to refactor, we’ll do it later”, etc.  
And no, administrative measures (“don’t use --sloppy”!) don’t always work.

---

<div class="post-metadata">

**Author:** ![IntegratedQuantum](https://ziggit.dev/user_avatar/ziggit.dev/integratedquantum/32/782_2.png) [@IntegratedQuantum](https://ziggit.dev/u/IntegratedQuantum)\
**Post date:** [November 21, 2023, 11:14am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/16 "2023-11-21T11:14:43Z")

</div>

> [@Durobot](#):
>
> The thing I am worried about is not somebody having an option to disable guardrails while playing in his/her sandbox, but that this option is going to be (ab)used “in production environment”. E.g. “we need this feature last week, no time to refactor, we’ll do it later”, etc.

Isn’t that way of abuse already there with `--autofix`?  
Honestly I think autofix is even worse than sloppy in that regard, since at least with sloppy we can get the errors back by removing the flag later.  
Also “don’t use --sloppy in production” can be enforced by the project manager with CI, while --autofix usage cannot even be detected reliably.

---

<div class="post-metadata">

**Author:** ![slonik-az](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@slonik-az](https://ziggit.dev/u/slonik-az)\
**Post date:** [November 21, 2023, 11:21am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/17 "2023-11-21T11:21:48Z")

</div>

In early days of Rust (before 1.0 release) there was lot of pressure to make borrow-checker optionally replace errors with warnings. But Rust team resisted and now memory safety guaranteed by borrow-checker is the Rust’s main selling point. Unconditionally barring sloppy code from compiling is a feature not a bug.

---

<div class="post-metadata">

**Author:** ![Durobot](https://ziggit.dev/user_avatar/ziggit.dev/durobot/32/447_2.png) [@Durobot](https://ziggit.dev/u/Durobot)\
**Post date:** [November 21, 2023, 11:31am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/18 "2023-11-21T11:31:57Z")

</div>

I’m unfamiliar with `--autofix`. What is it?

> [@IntegratedQuantum](#):
>
> Also “don’t use --sloppy in production” can be enforced by the project manager with CI

It can be enforced but it doesn’t necessarily have to be. Like I said, there are circumstances when you will be tempted (or outright pushed by the management) to skip the checks and just ship the next release already.

---

<div class="post-metadata">

**Author:** ![IntegratedQuantum](https://ziggit.dev/user_avatar/ziggit.dev/integratedquantum/32/782_2.png) [@IntegratedQuantum](https://ziggit.dev/u/IntegratedQuantum)\
**Post date:** [November 21, 2023, 11:40am UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/19 "2023-11-21T11:40:03Z")

</div>

> [@Durobot](#):
>
> I’m unfamiliar with `--autofix`. What is it?

It automatically inserts `_ = ` and other fixes to compiler errors like this: [stage2: --autofix proof-of-concept by andrewrk · Pull Request #12803 · ziglang/zig · GitHub](https://github.com/ziglang/zig/pull/12803)  
It wasn’t added to the language (yet?), but zls basically does the same thing.

---

<div class="post-metadata">

**Author:** ![slonik-az](https://ziggit.dev/letter_avatar_proxy/v4/letter/s/ebca7d/32.png) [@slonik-az](https://ziggit.dev/u/slonik-az)\
**Post date:** [November 21, 2023, 1:21pm UTC](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238/20 "2023-11-21T13:21:54Z")

</div>

If you absolutely have to have a `var` that you do not mutate at the moment, there is an officially blessed (by the PR author) escape hatch:

```zig
var x: i32 = 0;
_ = &x; // makes compiler happy. `&` promotes x to l-value
```

[Next page](https://ziggit.dev/t/error-local-variable-is-never-mutated/2238.md?page=2)
