5 ms·
Zig has defer. And C has free, but you have to remember to use it and use it correctly every single time instead of the memory working by default with no inter
by CyberDildonics 1y ago
Zig has defer.
And C has free, but you have to remember to use it and use it correctly every single time instead of the memory working by default with no intervention.
Says most people in the field of software correctness
Not true, the last 30 years have had much safer languages than before java, scripting languages, modern C++ and rust.
That's true, but these are not memory safety guarantees.
Pragmatically they mean you don't have to worry about bounds checking or memory deallocation and it stops being a problem. Zig doesn't have this and it doesn't have safety guarantees either.
- pron 1y ago> And C has free, but you have to remember to use it and use it correctly every single time instead of the memory working by default with no intervention. Tangential, but memory leaks are not considered a safety issue, especially by those who do like to contrast with Rust (as it isn't prevented in Rust). If we're talking about features that help (though not completely avoid) some bugs, you can't just consider the features C++ has and Zig doesn't, but also consider the relevant features Zig has and C++ doesn't. Like I said, I don't know which of those two languages results in more correct programs (just as I don't know the answer for Zig vs Rust), but I do know that Zig offers more safety guanrantees than C++, and Rust offers more safety guarantees than Zig. I certainly don't claim that more safety guarantess always equals more correctness at a lower cost. Even more tangentially, in the Java world we have this thing called "integrity" (https://openjdk.org/jeps/8305968 https://openjdk.org/jeps/8305968) which is the ability of Java code to locally establish inviolate invariants that are guaranteed to hold globally (unless the application author - importantly not any library code - explicitly allows them to be violated). C++ scores quite low on the integrity front, as virtually all intended invariants can be violated without a global flag, sometimes in ways that are hard to detect. In both Rust and Zig, integrity violations are generally easier to at least detect (although in Zig they're sometimes harder to establish in the first place; this is intentional, and I don't entirely agree with the justification for that, although I can see its merits in a low-level language). > Not true, the last 30 years have had much safer languages than before java, scripting languages, modern C++ and rust. I don't see how that contradicts what I said, especially since language that offer even more correctness - such as Idris or ATS - have had effectively zero adoption. The languages that have succeeded are safer than C or FORTRAN, but also clearly compromise on what they offer (compared to Idris/ATS) because of costs. They very much embody the an acceptance of tradeoffs, and much of the memory safety in most safe languages is offered through GCs, that come with the cost of higher memory footprint. If anything, their growing popularity has come due to advancements in GCs. Rust (you brought it up this time) is particularly interesting, because it offers something different than before to prevent UAF but at a higher cost than previous popular safe languages. While I don't know how popular Rust will be in the future, its current adoption is quite significantly lower than any language that's ever become popular at the same age. > Pragmatically they mean you don't have to worry about bounds checking or memory deallocation and it stops being a problem I haven't noticed that either one of these has "stopped being a problem", and I think that those who either sell or buy Rust do so because they believe these are still significant problems in C++ (and I would agree, except I think there are worse problems in C++ - that Rust, unfortunately, adopted - even with respect to correctness, that Zig attempts to solve). > Zig doesn't have this and it doesn't have safety guarantees either Zig definitely has safety guarantees around bounds and numeric overflow that C++ doesn't.
- CyberDildonics 1y agomemory leaks are not considered a safety issue Who told you that? in the Java world we have this thing called "integrity" Your claim was that zig is 'safer' than C++ Zig definitely has safety guarantees around bounds and numeric overflow that C++ doesn't. This can be built in to a class too if someone really wants a bunch of branching in their math. It seems like now safety is being redefined to say that memory leaks don't count and numeric overflow needs to be done like zig. If your program leaks memory, it eventually crashes if it runs indefinitely and that means you need to free memory, which means you need to free it at the right time only once.
- pron 1y ago> Who told you that? There is no one definitive definition of memory safety, but it generally refers to things that can lead to undefined behaviour (in the C and C++ sense), usually due to "type confusion" (or sometimes "heap pollution"), i.e. referencing an address of memory that contains data of one type as if it were another, which can happen due to both bounds or UAF violations. Memory leaks don't cause undefined behaviour. > This can be built in to a class too if someone really wants a bunch of branching in their math. Let me say this again: The Zig language, just like Rust, guarantees that there are no bounds violations (except in syntactically demarcated unsafe code). C++ just doesn't do that. That is not to say that the lack of this guarantee in C++ means you can't write correct programs in C++ as easily as in Zig or in Rust, but it is, nevertheless, a difference in the guarantees made by the language. > It seems like now safety is being redefined to say that memory leaks don't count and numeric overflow needs to be done like zig Memory unsafety is generally considered to be some subset of undefined behaviour (possibly including all undefined behaviour). Out-of-memory and stack overflow errors are definitely problems, but as they don't cause undefined behaviour (well, depending on stack protection) they're not usually regarded in the class of properties called memory safety. Numeric overflows, on the other hand, might also not be regarded as memory safety, but they are very much undefined behaviour in both C and C++.
- uecker 1y agoMemory leaks are also a safety issue. Especially not running destructors can be a safety issue, but also a resource leak is at least a DoS. IIRC Rust also included not having memory leaks earlier in their definition of memory safety, but dropped it later.
- scrubs 1y ago>C has free; zig has defer But even in a c++ destructer if you forget to dealloc a private heap allocation ... then you're in the same darn place.
- CyberDildonics 1y agoAnd if you divide by 0 your program still crashes. The reality is that you can use vectors for memory allocations and you never have to worry about it. If you do need to wrap resource allocation, you do it once, test it and it will probably work from then on. This is much better than the alternative of having to remember to free the memory, close the file, unlock the mutex correctly every single time you need one.
- pron 1y agoI don't agree that "you never have to worry about it" unless you're also using smart pointers, which is rarely what I want. I think that the alternative where all allocations and deallocations are made clear (in Zig, allocating routines are "coloured" by convention) is the better alternative, at least for the kind of low-level programming I do and for my way of thinking about low-level code. When I write code where I don't want to see or worry about each implementation detail or see exactly where and when each operation is executed, I use Java.
- CyberDildonics 1y agowhich is rarely what I want. If you don't want memory leaks, it probably is what you want. There isn't a ton of difference between putting a delete in a destructor and using a smart pointer, but the best approach is to go beyond smart pointers and just use a vector, which does everything for you. A lot of this seems like you haven't done a lot of modern C++ to see how elegant and smooth it is.
- pron 1y ago> If you don't want memory leaks, it probably is what you want. No, sorry. > A lot of this seems like you haven't done a lot of modern C++ to see how elegant and smooth it is. It's true I don't want to use modern C++ (except for certain compile-time tests), and that's because when I write low-level code what I care about the most is being able to see the machine instructions that will be emitted, especially the ones related to memory management (I don't care so much about the computational instructions; the compiler, and the CPU, will rewrite them dramatically anyway). If I find myself needing pretty abstractions, I reconsider my use of a low-level language. That's also why I'm philosophically opposed to the concept of zero-cost abstractions. What I want from C++ that C doesn't give me is templates and some other compile-time stuff, which are much more convenient for me than C macros. I don't want any implicitness in my low-level code. Zig gives me exactly what I want from a language that specialises in low-level code. My problem with zero-cost abstractions is that they result in code that looks high-level, while still only really having a low abstraction level (what I mean by a high or low abstraction level is the extent to which I can make local changes without influencing non-local code). The resulting code looks pretty on the page, but makes me work a lot harder to understand what is being executed and when. When I don't want to care about such details, I use Java. Just last week I had an interesting discussion, that's somewhat similar to this, about Haskell with a colleague. He said something like, look how clearly you can see the algorithm on the screen. And I said, yes, it looks great when trying to understand what it does by reading, but it's terrible to understand when you try analysing it in the debugger or profiler. The point is that there's different kinds of information that code can communicate. Sometimes you want just the function of the algorithm to be clear and want the language to hide execution details, and sometimes you're just as interested in the execution details.