5 ms·
1. Lack of memory safety is a big problem particularly because it's a common cause of dangerous vulnerabilities, but spatial safety is more important than tempo
by pron 1y ago
1. Lack of memory safety is a big problem particularly because it's a common cause of dangerous vulnerabilities, but spatial safety is more important than temporal safety for that reason, and Zig does offer spatial safety.
2. Other important issues of concern when it comes to security/correctness are language complexity and compilation speed. A complicated language with lots of implicitness can obscure bugs and make reviews slower. Slow compilation reduces the iteration speed and harms testing. Zig focuses on these two. The language is simple, with no implicitness - overloading of any kind is not allowed and neither are any kind of hidden calls. Even if security were the only concern, it's not clear at all how much complexity and compilation speed should be sacrificed for temporal safety. Remember that it's easy to classify bugs by technical causes, but more diffuse aspects, like testing and review, are also very important, and Zig tries to find a good balance.
3. Nevertheless, the language is still very expressive [1]. In any language, you want the algorithm to be clear and with neither extraneous nor important hidden details for that domain. I think Zig gets that about right for low-level programming (and C++ doesn't).
For me, the #1 problem with C is lack of safety and the #2 problem is lack of expressivity. With C++, the main problem for me is language complexity and implicitness, with slow compilation and lack of safety tied for number 2. So Zig is as expressive as C++. but not only safer, but also much simpler, and compiles faster (and improving compilation speed further is an important goal).
[1]: I say that two languages are equally expressive if, over all algorithms, idiomatic implementations in both languages (that are roughly equally clear) differ in length by no more than a linear relation with a small constant.
- mi_lk 1y agoCan you say more about spatial security v.s. temporal security and how Zig does them?
- pron 1y agoSpatial memory safety means that a language (at least in its subset that's designated "safe") doesn't allow you to manufacture pointers into memory that may contain data of a different type than what's expected by the pointer (we'll call such pointers "invalid"). The classic examples of spatial memory safety is guaranteeing that arrays are never accessed out of bounds (hence "spatial", as in pointers are safely constrained in the address space). Zig guarantees (except when using delineated "unsafe" code) such spatial safety. Temporal memory safety is the guarantee that you never access pointers that have been valid at some point in time after they've become invalid due to reallocation of memory; we call such pointers "dangling" (hence "temporal", as in pointers are safely constrained in time). The classic example of this is use-after-free. Zig does not guarantee temporal safety, and you can accidentally have a dangling pointer (i.e. access a one-time valid pointer after it's become invalid). Invalid pointers are especially dangerous because, in languages where they can occur, they've been a very common source of exploitable security vulnerabilities. However, violating spatial memory bounds is more dangerous, as the result is more easily exploited by attackers in the case of a vulnerability, as it's more predictable.
- pRusya 1y ago> So Zig is as expressive as C++. but not only safer, but also much simpler, and compiles faster Tbh syntax-wise Zig feels more cryptic[1] at first than C++. [1] e.g. `extern "user32" fn MessageBoxA(?win.HWND, [*:0]const u8, [*:0]const u8, u32) callconv(win.WINAPI) i32;` from https://ziglang.org/learn/samples/ https://ziglang.org/learn/samples/
- pron 1y agoI think that's just a matter of syntax habits, presumably because you're already familiar with C++ syntax. The syntax in your example is especially "cryptic" simply because it's an FFI signature (of a function that's not written in Zig and doesn't use the normal Zig data representations).
- tredre3 1y agoTo be clear the equivalent C++ code is: #include <windows.h> extern "C" __declspec(dllimport) int __stdcall MessageBoxA(HWND, LPCSTR, LPCSTR, UINT); // or extern "C" __declspec(dllimport) int __stdcall MessageBoxA(void *, const char[], const char[], unsigned int); It's not exactly a stellar improvement.
- npalli 1y agoLol, no this is the equivalent #include <windows.h> int main() { MessageBoxA(NULL, "world!", "Hello", 0); return 0; }
- deleted 1y ago[deleted]
- bjackman 1y agoI guess this must vary by usecase, but in the Linux kernel work I do, expressiveness is just not an issue. C is a dumb language, it's fine. Coding is just such a small part of the engineering task. Schlepping to write nontrivial stuff in C can be a drag but it's just such a minor thing compared to the task of getting OS software designed correctly that I am not really excited about trying to improve on that axis. Whereas the memory safety issue is totally fundamental and totally terrifying. There's no other way to solve it than with a new language. The cost of changing languages is staggering but we have no choice. Yet... Paying that cost and not eking out the maximum safety benefit that's practical... Seems a bit dodgy to me.
- pron 1y ago> There's no other way to solve it than with a new language. That's not true, though. If memory safety is the only thing that you need and C doesn't have, there are products that offer memory-safety proofs for C (e.g. https://www.trust-in-soft.com https://www.trust-in-soft.com). You do need to add some lifetime annotations and may want to change your code here and there, but it's overall much cheaper than a rewrite in a new language. I believe such solutions are more popular, too; few companies - even and especially those that care primarily about correctness - are crazy enough to justify a rewrite of an existing product just for memory safety. > Paying that cost and not eking out the maximum safety benefit that's practical... Seems a bit dodgy to me. The cost is not the same, though (and if you only consider rewrites, as I said, there are better options). It sounds like you're saying that any cost is worth any added safety. I don't think that's true, but if it were, then something like ATS is probably what you're after (it isn't, though, because it's practically nobody's choice). Anything short of that is some compromise between cost and safety. Rust's compromise is just different from Zig's. They're both significantly safer than C and a far way off from ATS. Everyone seems to agree that the sweet spot is somewhere on that spectrum - not C, not ATS - but there's no agreement on where.
- kobebrookskC3 1y ago> there are products that offer memory-safety proofs for C what does the c checked by this tool look like? for an example like https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=18cd3ce3a459de7c41563eef542521b7 https://play.rust-lang.org/?version=stable&mode=debug&editio... , does the tool accept the assignment with f and reject the assignment with g?