I feel ashamed for not noticing it, i should’ve been more observant. Thank you for a quick reply! The compiler indeed led me the wrong way
There is nothing to be ashamed of. We all make mistakes like this. It’s hard to notice a missing &
, especially if the compiler is pointing somewhere else.
That is, by no means, something you should be ashamed about.
You simply tripped over one of the many beefs people have been complaining about with Zig being so stupidly pedantic. The fact that pedantic “errors” stop compilation dead and prevent you from getting to what is a genuine error is a real glaring fault in Zig.
In my opinion, Zig needs to be a lot more complete before it starts trying to be so pedantic.
Personally, I think these checks are like Van Halen’s bowl of M&M’ s, a seemingly frivolous demand that actually functions as a useful test of whether people have done their job. At the same time though, it’s obvious that people aren’t going to do a good job when they’re constantly wasting time picking out brown M&M’s instead of doing what they’re supposed to do.
Could we all at least agree that there are times when one just does not want to focus on these automated errors? Times when, so to speak, pursuing “perfect spelling” would go against producing “compelling prose”?
I will repeat myself, once again: I would never publish a manuscript with known spelling errors. That doesn’t mean I want to focus at all times on the spelling.
These automated errors are (in my mind) that: spelling errors, that I should fix before “publishing” my work. When I am about to publish, it is fantastic that the compiler will have my back in finding these. But I feel that, before I reach that stage, these errors hinder my flow. It seems I am not the only one to feel this way.
Peace!
I just went through the process of converting quite a few vars to consts in one of my projects. Tedious? Yes. But I felt like the compiler was really helping me out here, making my code (dare I say it) more correct. I know the term correct can trigger reactions if it implies that other code is incorrect. But in this case, I think it’s the right term. The compiler is asking me: Hey, if you never mutate this variable, shouldn’t it be a const? And for this project, the answer was yes all the time.
Aside from the code more faithfully reflecting the intention and use of a variable, I understand that there are also real-world benefits that result from these fixes, like more opportunities for compiler optimizations. So in the end, I appreciate this type of help from the compiler, but this is obviously personal preference here.
A compromise proposal: Let Debug mode ignore the unused/unmutated errors but all Release modes enforce them. While debugging I want to have all my variables around even currently unused/unmutated ones, just in case you put a breakpoint on their declaration line.
This has been proposed many many times, for all the errors in Zig that could be warnings, and it has been rejected every time. I think Zig is right on this one, sometimes I spend large amounts of time in Debug mode before testing my code in Release, and I don’t want all that code to be in sloppy mode.
I am personally fine either way. After two years of Rust Borrow Checker beating me into submission the amount of “enforcement” performed by Zig compiler is minuscule in comparison.
Sure, this would be one way of going about it. Another way would be having a command-line option, or any other way of signaling “I’m experimenting, leave me alone for now”. Any of these would work (for me at least).
There’s prior art in C compilers on how to deal with this. Like -Werror
to turn on warnings-as-errors and also -Werror=<name>
and -Wno-error=<name>
to enable/disable a warning to be promoted to an error.
IMO this is not something I’d attach to the Debug vs Release split, rather these should be orthogonal controls.
Having had to work with CI jobs where millions of lines of code were compiled through various compilers (multiple GCC versions, MSVC, Clang) and compiler configurations (debug, release, and cross targets), I do not look back on warnings-as-errors fondly at all. Different versions of GCC can output different warnings. Similarly, different optimization settings could trigger a different set of warnings. Compilers from different vendors (GCC, Clang, Microsoft) output different set of warnings. And different CPU backends might emit different types of warnings. Turning on warnings as errors in such a setting, esp. for 3rd party code, ends up being a massive time sink and getting anything through CI was a major PITA.
Sure, there’s only one Zig compiler for the time being, so these types of problems have not realized themselves. But even just admitting that Debug and Release builds have different error semantics takes a step towards that type of combinatorial explosion of PITA. But I wouldn’t be surprised to see for example different Zig compiler versions start to emit slightly different warnings (as the implementation of some warnings are dependent on f.ex. the types of optimization your compiler can do).
FWIW, I didn’t mind the “const vs var” business as much as the “unused variable” warning. But what will happen as new types of warnings get added to the compiler? Will new types of workarounds need to be built into ZLS, like was built for the “unused variable” case? Sure, I don’t leave unused variables into my code when I’m done with it and ZLS fixing those is also kind of cool, but I find nowadays also hate saving code in VSCode because ZLS “fixes” my unfinished code. I’d just rather this be a warning which I’d clean up when I’m finished with the code.
That’s too much.
Most people who want optional simply want a command line flag that works when debug is also engaged.
I think this is where things are finally going to come to a head. Now that there is a packaging mechanism, people are going to start using more code that they don’t have direct control over.
The next time one of these idiotic “errors” comes online, there’s going to be a bunch of repos that now fail to compile that are dependencies.
People will forgive being unable to compile because of genuine language semantics changes. People will be actively pissed off about being unable to compile because of a sudden pedantic “error” that isn’t.
While I’m not that fond of rust in general. I think they have solved this issue pretty well by allowing crates to define what “edition” of language they are using, so that the rust compiler can relax its checks.
https://doc.rust-lang.org/edition-guide/editions/
Compiler flags with C are also not silver bullet and projects tend to break depending on compiler version etc.
Flags are also notorious for being badly documented and bizarrely hard (for whatever reason) to search for on google. It’s one of those “how do I know that I needed that?” kind of problems.
Otherwise, welcome to the forum @Cloudef
I think editions are a nice idea from a user perspective, but I think a feature like this also creates significant burden for the language developer, because they now have to be committed to not only creating one very stable version but also keeping all previous editions working. It seems rust added that feature with version 1.0 and I think adding such a feature before 1.0 doesn’t make sense.
Personally I am not sure I want it at all, because while that feature could spare me from having to update dependencies, it also means that the language carries a bloating tail of older ways of doing things. Basically: not having editions, is a feature too, the feature that old code, gets old and thus is used less and less, it also is a bit of a health check, if people still care about that code it will be updated, else it will just rot and be forgotten. Another thing is with editions there may be code that still works, but doesn’t use new features that would make it work better, if people have to touch the code there is at least a chance they will try to improve the code while they are updating it.
That will work as long as the language stabilizes significantly. Otherwise the package manager seems kinda pointless as you end up forking every dependency anyways to keep things compiling.
I think the editions are nice balance. The editions don’t cover major language changes. Only “skin deep” stuff, like new warnings / errors, or keywords.
.dependencies = .{
.lambda = .{
.path = "./deps/zig-lambda-runtime",
},
.json = .{
.path = "./deps/json",
},
.getty = .{
.path = "./deps/getty",
},
.sqlite = .{
.url = "https://github.com/vrischmann/zig-sqlite/archive/3d8e617c43d047b87bcbf74e9b6d26caf9f3f4f0.tar.gz",
.hash = "1220f246e113cc7aa245f681d8c5b57f87af391b199cc0eb8eca42c3b697c2664677",
},
},
If you’re not testing for release, then your approach is wrong. The change from debug to release is far more greater more than selecting a different optimization setting. Sizes of structs can actually change. Code that is safe with runtime safety enabled might open gaping security holes when it’s disabled. Testing at release should needs to happen as soon as possible.
When code that has only been tested at debug fails to compile when the level’s bumped to release, it’s a good thing. That’s a feature not a bug. That’s the brown M&M (for those who know the Van Halen story).
A while ago I created a fork of Zig whose only purpose is to remove the unused variable error with a flag --alllow-unused or -u. It hasn’t been updated since 0.10.1 and I’m not sure how much work it would take to bring it up to date.
I fully agree with everything you said about unused variable error. It is a good thing when publishing code for others to read. It is a bad thing when when you are doing controlled experiments in your own code, where the control group is created by disabling a certain chunk of code.
Therefore I promise to never publish any code I write while using --allow-unused, and I hope everyone else does as well, for the good of the Zig community. But I also love having this flag for local development.
Well, let’s change Zig license to include a prohibition on --allow-unused in any production code, and then the problem is solved, I’m 100% sure
(just joking, please don’t regard this as an attempt to engage in an argument)
I’m just gonna throw in my two cents here on human nature from my own personal experience.
I used to work at a paper mill many many years. The number of safety features and rules in place was just mind boggling. The thing about all those rules and safety features was that they were in place because someone else had paid the price in blood. Someone either died, was dismembered, or their life was drastically changed for the worst because of an injury. You can’t do this a certain way because the risk is too great to bodily harm.
The thing is even knowing all this and likely having witnessed accidents taking place themselves those safety precautions got bypassed.
If a person is willing to risk their lives just to get the job done faster even in a place with a history of bloody accidents then I have no doubt that people would abuse a system that allows them to. That is human nature. You may think you wont do it but for every person that won’t abuse it there will be a 100 that will.