Live data from Hacker News

Hobby x86 kernel written with Zig

github.com

151–160 of 229 posts

Re: Hobby x86 kernel written with Zig

#151
post #44

Earlier quoted context omitted.

I wouldn't call Zig's comptime "C++-style." Unlike Rust, there's very little in Zig that is borrowed from C++. Zig's error reporting and comptime makes it easy to write arbitrary compile-time checks, so Zig uses a single construct and keyword, comptime, to replace all special instances of partial evaluation: generics, concepts/traits, value templates, macros and constexprs. The main difference between Zig and Rust is…

> There is also the difference in their approach to safety, but that's a complicated subject that ultimately boils down to an empirical question -- which approach is safer? -- which we don't have the requisite data to answer. We do have the requisite data to answer whether preventing use-after-free is better than not preventing it. You can argue (not successfully, in my opinion) that it's not worth the loss in produc…

> but it's impossible to argue that not trying to prevent UAF is somehow safer.

It might be possible. Someone might prove that preventing UAF necessarily increases complexity somewhere else. Like one of those laws of thermodynamics, but for software.

Re: Hobby x86 kernel written with Zig

#152
post #58

Earlier quoted context omitted.

The ammount of unsafe blocks is pretty small compared to the rest of the code. Which means those parts can be reviewed more extensively. If anything your argument is pretty goofy.

What I find is that, while Rust unquestionably improves the security of software, the argument that you can minimize unsafe code and thoroughly inspect it doesn't tell the full story, because in my experience people end up writing general-purpose unsafe blocks, and while they are controlled by the "safe" outside, the sequence of actions the "safe" code tells them "unsafe" code to execute can lead to subtle bugs.

yep, 100%

I personally think the Rust community has missed the biggest advantage of unsafe, and that's tooling. Imagine an IDE that could highlight and warn when touching state that is accessed in unsafe blocks, or when state being accessed in unsafe blocks isn't being properly tested.

Or tools that kick off notification for a required code review because code that touches state used by an unsafe block got changed.

To me, these sorts of things will have a far greater effect on security and stability than just the existence of the unsafe block in code.

Re: Hobby x86 kernel written with Zig

#153

Earlier quoted context omitted.

The problem with C-style bitfield values/arbitrary-sized integers is that they don't have addresses, so you can't take references to them. This means that you need special cases everywhere, and it increases the complexity of the language a lot. In Rust, integers often have methods that take self by reference, which demands an actual address. For these reasons, in Rust I think it's better that arbitrarily-sized intege…

In Zig they do; here is an example: https://clbin.com/HlJ0X Output: Test [1/1] test "bit field access"... *align(:3:1) u3 All 1 tests passed. Zig's pointer type has optional metadata to describe alignment, sub-byte offset, and SIMD vector element index. This generally makes things just work, and you'll get a compile error if you expected an unadorned aligned pointer. If I were to swap: - fn deref(ptr: var) u3 { + fn…

How do you deal with atomicity though? A big deal in Rust is that you can only have one mutable reference to an object at any given time which prevents all sorts of aliasing issues, but here if you have two mutable fat pointers, one to and and one to b, and you attempt to write them without synchronization you're going to have a big problem, won't you?

This is the main risk with bitfields in C, it makes reads and writes that appear to be independent actually access the same memory cell behind the scenes. I'm not convinced by the idea of adding even more magic on top of it to be honest, it is true that packing and unpacking bitfields is annoying and requires some boilerplate but in the end that is how it the hardware does it anyway.

Re: Hobby x86 kernel written with Zig

#154
post #25

Earlier quoted context omitted.

You could argue that it's what these languages do, the C heritage is very strong in every one of them. The problem is: do you want to maintain full backcompat or are you willing to break things to do it cleanly? If you do the former you end up with something like C++ which retains almost complete compatibility with C (but they you have a lot of baggage to carry around, which may get in the way at times) or you're wil…

> If you do the former you end up with something like C++ That's a pretty awesome place to be, as C++ is one of the most successful programming languages in history. Perhaps there are lessons there. > or you're willing to break things and then why not take the opportunity to improve the syntax and get rid of the cruft? Break things just for the hell of it is not much of a tech argument. C is already pretty light, and…

C++ is hugely successful, that's true, but is there a need for an other C++-style language? C++ already feels like 10 languages under a trenchcoat anyway, whatever your style you'll probably find a subset of it you'll like. I think it showed how powerful "C-with-classes-and-the-kitchensink" can be, and also the limits of the concept.

C is light but it does have some things worth breaking IMO. Type inference is something I dearly miss when I write C these days (and I do that a lot). C didn't have any generic programing for a long time (if you don't count macro soup, that is), now it has some very limited support but it still looks like banging rocks together compared to more modern languages.

C's unsafety is legendary, and segfaults a common problem even for experienced programmers. Rust's lifetimes makes them impossible by design for safe code.

You may not like that of course, but those are all good reasons for experimenting with other paradigms.

>Arguably, the preprocessor is orthogonal to the programming language itself. I fail to see how that's relevant.

Arguably it is, practically it very much isn't.

Re: Hobby x86 kernel written with Zig

#155
post #137
post #109

Earlier quoted context omitted.

Does the standard library use malloc/free or does it depend on the GC? This is the part that's puzzling to me, if the stdlib depends on GC then it's harder to say that GC is optional. Technically optional but not super practical.

The majority of stdlib modules does not depend on GC. Also, the new ARC memory manager replaces GC and can run in a kernel.

No that's not true.

As soon as you use sequences or strings or async you depend on the GC.

You can however compile with gc:destructors or gc:arc so that those are managed by RAII.

Re: Hobby x86 kernel written with Zig

#156
post #76

Earlier quoted context omitted.

comptime does not replace macros though...there is no way to manipulate AST in zig, nor will there ever be, according to the author.

Which is the right call really. It is valuable to have the code you're looking at actually be what it appears to be.

It's always a trade-off and placing the cursor correctly is tricky. Things like macros, operator overloading, metaprograming, virtual calls, exceptions or even function pointers are effectively "obfuscating" code by having non-obvious side effects if you don't have the full context. On the other hand if you push the idea too far in the other direction you end up with basically assembly, where you have an ultra-explicit sequence of instruction to execute.

It's very easy to come up with examples of terrible abuse of these features that lead to bad code (like for instance if somebody was insane enough to overload the binary shift operator << to, I don't know, write to an output or something) but it also gives a lot of power to write concise and expressive code.

Re: Hobby x86 kernel written with Zig

#157
post #51

Earlier quoted context omitted.

As an ancestor in this thread pointed out: it's hard/impossible to go without unsafe in a kernel. Proof (and they have a policy to only use unsafe when not otherwise possible): https://github.com/redox-os/kernel/search?q=unsafe&unscoped_...

yes, that's the point i'm making. saying "if you write your kernel in rust, it will be memory safe" is a little goofy, because writing kernels in rust requires you to drop into unsafe blocks way too often.

the million dollar question is what % of your code has to be unsafe in a kernel. At some %, it ends up not being worth the trouble. But if the % can be kept relatively low (say 5% or less) then you get a lot of value out of minimizing the surface area of the dangerous code.

Re: Hobby x86 kernel written with Zig

#158
post #6

Earlier quoted context omitted.

> I used to do this in Rust but I switched to zig for maintainability and readability over Rust. Can you expand on this ? I'm asking out of curiosity because I want to learn a "system" programming language (for whatever definition there is to this term). So far I briefly tried Rust and Nim and found the former more difficult to read. I know nothing about Zig, how would you place it between these two ?

In general you'll find that zig is easier to read than Rust (see the first version of this project in Rust [0]) because it's a simpler language. For kernel programming this is even more so the case: * zig has native support for arbitrary sized integers. In Rust I used to do bitshifts, Now I just have a packed struct of u3/u5/u7 whatever (see `src/pci/pci.zig`). Of course Rust has a bitflags crate but I didn't find it…

>"zig has native support for arbitrary sized integers."

I apologize if this is a naive question. Might you or someone else elaborate on where arbitrary sized integers are used or necessary in kernel programming? Don't they all ultimately need to get padded out for the CPU registers to work with them anyway?

Re: Hobby x86 kernel written with Zig

#159
post #146
post #122

Earlier quoted context omitted.

> We have a pretty good answer to the question "is ASan sufficient to prevent memory safety problems in practice" That is not the question we're interested in answering, and elimination of all memory errors is no one's ultimate goal, certainly not at any cost. By definition, unsound techniques will let some errors through. The question is which approach leads to an overall safer program for a given effort, and soundn…

P.S. > Notice that the working approaches have something important in common: a strong system that, given certain assumptions, guarantees the lack of memory safety problems. That's a very good point and I'm not arguing against it. It's just that even if it's true -- and I'm more than willing to concede that it is -- it still doesn't answer the question, which is: what is the best approach to achieving a required leve…

I would like to chime in by noting that Rust's mature form is borne of a very specific scenario, which is the web browser, software so complex that the "zero-cost" element is more like "actually possible to optimize" in practice. And a great deal of that complexity is accidential in some form, a result of accreted layers.

And in that respect, it's not really the kind of software anyone needs to aspire to; aspiring to write programs simple enough that Zig will do the job is much more palatable.

Re: Hobby x86 kernel written with Zig

#160
post #15
post #9

Earlier quoted context omitted.

I'm curious too, I'm quite familiar with Rust and never written any Zig in my life so I went digging through the source and I find the syntax remarkably similar for the most part. The only thing that stood out is that apparently you can drop the braces for single-line `if` bodies like in C whereas Rust makes them always mandatory but I'm firmly on Rust's side on this one. The part where Rust can get really messy is w…

If you want more syntax weirdness: tab characters are illegal.

Really? I might have to take a look at this language then. Making tabs illegal whitespace might very well be a proxy for other good design decisions.
Post reply on HN