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.
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++.
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.
You said that already, but when saying zig is safer than C++, pragmatically it isn't because C++ bounds checks in the standard library but zig can never have the automatic resource management that C++ has, and that's what people use all day every day.
We keep talking about completely different things. If we're talking about "features that can help reduce some bug" then C++ or Rust have some that Zig doesn't and Zig has some that C++ or Rust don't. Which ends up more pragmatic is an empirical question that's hard to answer without data, but certainly focusing only on what C++ has and Zig doesn't while ignoring what Zig has that C++ doesn't is a strange way to compare things (BTW, I've been programming in C++ for almost 3 decades, and I really dislike RAII and try to avoid it).
But if we're talking about memory safety - which is something very specific - then, for whatever it's worth, Zig is more memory-safe than C++ and Rust is more memory-safe than Zig.
We keep talking about completely different things.
You said zig is safer than C++, then to make that argument you keep trying to redefine what safety means to include only features in the language syntax but not done in libraries while saying memory leaks don't matter and automatically freeing memory correctly doesn't matter.
I am not redefining what safety means. I am using the same definition of safety used in this entire thread by those debating the pros and cons of Rust being safer than Zig.
I definitely didn't say that memory leaks don't matter. They could possibly matter more than memory safety. They are just not called memory safety bugs, or code injection bugs, or off-by-one bugs. Memory safety is a name given to a class of bugs that lead to undefined behaviour in C or C++. It's not necessarily the most important class of bugs, but it is one, and when we're talking about preventing code injection or memory safety issues, we're not talking about preventing memory leaks - even if they're worse.
Now, if you want to talk about memory leaks and not memory safety (again, it's just a name given to some bugs and not others) then C, C++, Zig, and Rust, do not prevent them. Java prevents the kind "I forgot to free this object" kind, but not "I forgot about this object" kind.
Now, because unlike memory safety, none of these languages prevents memory leaks, it's really hard to say which of them leads to the fewest memory leaks. You really like C++'s destructors and find them useful, I really hate C++'s destructors and find them harmful, and we all have different opinions on why our way is better when it comes to memory leaks. What we don't have is data. So you can say having destructors helps and I can say no they don't until the end of time, but there's no way of knowing which is really better. So all we can do now, is to use the things we find useful to us without making broad generalisations about software correctness that we can't actually support with any evidence.
I would say: not the ones with spooky implicit actions and hidden heap allocations, but we won't know until we actually have data.
When writing in a low-level language, I always want to know where I'm allocating and where I'm deallocating. Zig makes allocations easier to spot than in C/C++/Rust, and deallocations easier to spot than in C++/Rust. That's just how I like it. I'm not saying everyone must have the same preference.
You might like making and freeing every heap allocation but that doesn't mean it's safer. Every other language would be in the category of 'hidden heap allocations' to a much greater degree. People who understand it don't feel that it is 'spooky'.
I didn't say it was safer, but by "safety" here I don't mean something that will likely work, but an absolute guarantee that it will regardless of what client code does (with the exception of clearly marked unsafe code that's easily found). C++ doesn't offer this kind of safety for pretty much anything.
So we're talking about the likelihood of making a mistake - and of not easily finding it - in the absence of safety. Without any empirical data, all we have to rely on is personal preferences and gut feeling, and those are different from one person to the other. Even expert programmers often violently disagree on what's "better", and I think that's because things can be better or worse for different use cases, but also better or worse for different programmers working on the same problem.
I would like there to be more empirical studies, but I also think we can probably live without them, because software is such an important economic activity that it's under significant selective pressures. If one approach significantly decreases the effort of delivering more value in software, it will spread almost universally (e.g. as unit tests have); the converse is that if something doesn't become universal, then it probably doesn't have a large universal impact.
No, you didn't. You wrote "You might like making and freeing every heap allocation but that doesn't mean it's safer." That is a very different claim (and one I didn't make) than "Zig is safer than C++".
Zig is safer than C++ because it makes some absolute guarantees that C++ doesn't, and C++ doesn't make any absolute guarantees that Zig doesn't. But no memory leaks is not a guarantee that either Zig or C++ make.
Zig and Rust guarantee that all Zig and Rust programs are free of out-of-bounds access (unless they explicitly use syntactically distinct "unsafe" operations). C++ makes no guarantee about all C++ programs that these two other languages don't make.
To what degree that matters is a perfectly fine subject for debate, but that particular thing - again, important or not - is how I (and others) define "safety" (as it pertains to a language), and I made it clear that that's the definition I'm using.
By that definition, memory leaks are not safe in C, C++, Zig, or Rust, but Zig is still safer than C++ because of other properties that are safe in Zig.
Memory 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.
The vast majority of catastrophic problems - nearly all of them, in the grand scheme of things - including those that can cause total system failure or theft of all data are not considered memory safety issues (which is one of the reasons that memory safety is overestimated or at least misunderstood, IMO, and why I prefer to talk about correctness in general). Memory safety refers to a specific kind of problems that correspond to undefined behaviour in C or C++. Memory safety issues are not neessarily any more or less sever than any other program weakness, it's just that for a long time they've been associated with low-level programming.
I'm not aware of any popular language - even a high level one - that prevents memory leaks with any kind of guarantee (although these come in different flavours too, and some kinds are prevented in Java). C/C++/Rust/Zig certainly don't.
Memory safety - as now being popularized by Rust in its current form - mostly corresponds to not having UB in C or C++. My point is that this not the only definition and not even the definition Rust started with.
Memory leaks are often a part of the definition of memory safety because otherwise it is trivial to fix use-after-free, i.e. simple never free the memory. Rust dropped this part because it was too hard. So in some sense the cheated a little bit.
Well, when Rust came out I had only been programming in C and C++ for about 15, maybe 20 years, but I think that even then we generally used memory safety to refer to problems that can cause "type confusion". In any event, given that none of the languages mentioned here - C, C++, Zig, or Rust - prevent memory leaks, I don't think that the question of whether or not we include it under the umbrella of memory safety could offer insight on the interesting distinctions between these languages.
I think it is relevant exactly because Rust exceptionalism is based on sloppy arguments that are fallacious because they narrow down topics and definitions in some invalid way, i.e. only considered memory safety while ignoring safety in general, only considering a specific definition of memory safety, only considering the safe subset of Rust, only accepting language-level safety, etc. until at the end it looks that Rust is extremely different to other languages while it is just some incremental step.
I completely agree, but given that even in Java, which eliminates the memory leaks Rust doesn't, programs still have bugs and security vulnerabilities, I don't think it's about what is and isn't memory safety. Most of the software that runs the world has been written in memory-safe languages for a very long time. It's more about understanding the significance and role of memory safety. With that comes the insight that it isn't binary and, while important (out-of-bounds access in C and C++ is, as far as we know empirically, one of the leading causes of security vulnerabilities), eliminating it has both a finite benefit and a cost that need to be considered.
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.