Although Ada has eventually got an open source compiler, and there are still around 5 vendors available, due to the way it got sold, its key use has been in the area of High Integrity Computing.
So unless that is the domain of the work, where no errors are allowed, which could possibly lead to loss of human lives, very few care of using Ada.
For the young generations, Ada is kind of something they hear it existed but they never seen live, even though it has enjoyed a regular presence at European FOSS conferences like FOSDEM.
So by being modern, Rust can appeal more to the younger generations, also some type system safety rules of Rust for parallel code can only be coded in Ada via SPARK.
Having only recently looked at Ada I don't really understand this. It does look like Ada offers a lot of really nice features that other languages haven't yet caught up to.
For example, SPARK allows formal definition of correct code behaviour within the function definition. This appears to me to mean tests are written into the function at the time you write the function. That's huge from a maintenance standpoint, and it likely provides extra information a compiler could take advantage of.
> where no errors are allowed, which could possibly lead to loss of human lives, very few care of using Ada.
Loss of life is one area, but surely anything financial would benefit from this - as well as anything dealing with personal data (e.g. identity management)?
So it's clearly not wrong, and is actually a totally well established idea well outside of the context of rust or C.
Remote code execution isn't a concern.
In C every single line of code that manipulates pointers, does string operations, uses arrays or unsigned arithmetic is a possible cause of memory corruption.
If you have a MMU, the runtime will/should protect against that by mapping a page as 'trap on write' and panicking/rebooting/signaling if you do, but if you don't, I don't think rust has any functionality to prevent it.
Or can you declare that your stack is x bytes, and have the compiler verify that no call chain will need more? (That typically would prevent the use of recursion, but that's not too bad)
Can you tell me more about them?
You're right that a summary seems hard to find; http://www.delorie.com/gnu/docs/gcc/gccint_124.html has some decent stuff in it, but given that it's random GCC docs, the details may not be 100% accurate today, I dunno, I'm on a flight layover right now, so that's all I've got at the moment :)
Static checks for stack overflows are infeasible.
Doing so doesn’t remove all useful programs, as the first Fortran compilers showed (they used a fixed addresses for all variables, be they local or global (that they did not support recursion is not that surprising, given that many CPUs of the time didn’t have a return stack))
That’s why I asked whether Rust supported such a thing. It would be very helpful, for example, if your build system would tell you that that difficult to test error handler would, if called, overflow the stack before you spent time and, possibly, lots of money, on trying to run it.
It also prevents the use of indirect calls/virtual functions, because they can hide recursion. That's Bad.
For comparison, I would say C and C++ (but to a slightly lesser degree) are also trivial to write buffer overflows in, it is definitely non-trivial in many cases to find and fix those problems, as the surface area is so large.
To illustrate this, it's trivial to write a buffer overflow in almost all languages that provide any sort of raw memory access or hardware instructions (ASM), even if through a module. It's trivial for me to create a buffer overflow in Python or Perl my including a module that allows direct assembly code access. The difference when using those languages is that when I run into a buffer overflow problem, I can be reasonably sure it's in a place where I bypassed the assurances provided by those languages, or in some included module that did the same (including just using a shared library). When tracking down a problem like that, I'll focus my attention on those spots, which makes identifying and hopefully fixing those problems easier.
Rust's "unsafe" is really an in-language way to provide a similar set of levels of assurance about how likely the code is to have problems of specific types, with assurances provides by the language and compiler. This is a step above what C and C++[1] provide, and thus welcome.
1: C++ provides some similar assurances based on types, but by nature of how "safe" code becomes "unsafe" when used in conjunction with unsafe portions, is much harder to assess at a block level, since you can't even be sure a line is safe until you've verified all the types used within it.
Every case where this is not true is a bug.
I've never tried the Python or Java equivalents and frankly don't know enough about them to even know whether your comment is accurate or not.
I find the notion that "explicit unsafe makes bugs less likely" to be suspect. It seems reasonable, almost tautological at first glance. But theory and practice are different animals.
But that is a big difference in the amount of unsafety per line of code.
As for better, that is in the eye of the beholder. I've never used embedded ADA, but I've slung my fair share of ADA code in higher level applications. For me, for reasons I couldn't describe, the syntaxes and grammars of C-like languages (C++, Rust) just feel more comfortable. ADA is a fine language, though, and a real pleasure to work with, too (it reminded me a lot of Pascal, which is what I learned in school).
Here's something else to consider, however: Rust (core rust, even without the stdlib) provides a fantastic set of built-in abstractions that would require lots of up-front development effort if one used C.
If your C programs are correct, there is no safety problem.
I can't speak to Ada.
That doesn't mean that Rust has no safety properties. It just means you have a TCB of nonzero size.
That's also true with any memory-safe language ever: you have to trust the compiler and VM. So if we accept your claim, then we also have to accept the claim that no memory-safe language has any useful safety properties. Needless to say, this is contrary to all the evidence.
> The reality is that one of the core selling points of the language was discovered to be unsafe due to some particularly complex combination of library features right before the 1.0 release.
Consider the chain of events that would have to happen to cause this unsoundness to lead to real-world problems (say, RCE), and compare that to the chain of events that routinely happen in order to cause a use-after-free in C++ to lead to the same problems. One is vastly more probable than the other.
I hope that Rust unsafe/safe concept makes the platform/applogic boundary more visible and explicit, so people follow these practices more often.
I don't think that's true. I'm writing an OpenGL library right now, diving into "unsafe" all the time to issue the FFI calls, and there's a measurable difference in the number of memory safety problems I've seen (zero thus far) compared to what I see in C++.
I think the friction of writing "unsafe" encourages small isolated abstractions.
Sadly in more than 30 years of career I never met one. Not even the BSD and Linux kernel devs, given the amount of entries on the CVE database.
Even Dennis complained about this, regarding the genesis of lint.
So I wonder where do they exist.
To be concrete: libpng, libjpeg, FreeType, etc. are not written by "morons". Can you write a JPEG decoder faster than libjpeg-turbo?
Note it wont affect me as I mainly use PIC micros