I'm not so sure I would. For one, Ada is in no way a niche language. For two, C (and C++ by extension) simply were not designed with safety or reliability in mind. I happen to think that it's fair to say that they weren't designed at all, in that C compilers existed before the first language specification, and the language specification was forced to accommodate their quirks. Cargo culting about C is fine and all, but it often leads to absurd claims that it is more suitable in any arbitrary domain than languages and compilers designed specifically for the domain.
I think I'd prefer that safety-critical code be written in languages that don't allow pointer arithmetic except in scenarios that can be proved via static analysis not to introduce multiple memory aliases. Expecting program writers and compiler authors to get these sorts of things right in C/C++ is just unreasonable.
Sure. But now you're retreating to a rather small set of applications. Ada has nice tooling and supports a pretty large number of platforms. I don't think you'll find many niches where not one of Rust, D, Swift, Ada, Java, Go, or the dozens of other memory safe(r) languages could do the job and only C or C++ are adequate.
Agreed on this. Ada has many solutions that I wish I had access to in C and C++.
In regards to efficiency, Ada as a language can be optimized to a greater extent than C/C++. It avoids the aliasing problem all together, ALIASED is a keyword in Ada that must be explicitly used, by default the compiler prevents aliasing! Everything else in the language is very unambiguous, a lot of checks are done at compile time, and if needed for performance, run time checks can be turned off on a selective basis.
Combined with the optional but enabled by default since-you-are-going-to-write-them-anyone bounds checking on parameters, and a type/subtype system that lets me ACTUALLY DEFINE the ranges of every parameter going in and out of my function calls, well, whenever I look at a bug fix, I do a mental check of "would this even be possible to do wrong in Ada?" and for about 30% of bugs, I'd say no.
Ada's main disadvantage from an embedded point of view is the hoops it makes people go through to do bit manipulation. It is understandable why, bit manipulation breaks the entire type system in every possible way, but a lot of embedded development requires it. At some point it'd be nice if the language had a keyword that just said "this variable can be abused, let it live dangerously."
It also has proper tagged types and built in syntax for circular arrays. Two bits of code I am sick and tired of writing again and again in C, and then having to explain to people what a tagged type is.
It is funny, from what I understand one of the old complaints about Ada was how verbose it was in comparison to C at the time.
Comparing modern Ada to modern C++, C++ has tried its best to equal Ada in verbosity, although C++11 fixed a good deal of C++03's excesses.
From what I can tell, Ada is still missing a good way to do really primitive bit operations in a simple matter. Then again, bit ops destroy Ada's type safety, so I can see why they were made difficult. Still, if one needs to start poking around the individual bits of arbitrary data, C makes that easy-ish. (I mean it could be a lot better, it isn't hard to come up with a better syntax than C's for bit-wise access)
But everything I have read about the latest Ada spec makes it seem like a nice language.
I also believe another problem is that Ada has always been a rather academic language in many ways. Where as for the longest time no one in the C community really talked about pointer aliasing (and I'm guessing if you took a random cross sample of programmers in the late 80s/90s, many of them wouldn't know what the term even meant), Ada requires you know about pointer aliasing just to use pointers at all!
Then there is the fact that the language syntax is defined in BNF, and the main reference pointed to for Ada is the official reference manual. On one hand, hey awesome, the language spec is freely available for all! On the other hand, it is about as readable as any other official spec. The experts who can easily understand the spec end up just pointing to it (after all it is so easy for them to read) and thus simplified explanations don't get created.
> In fact most of the people who complain about C++ would never even consider Ada.
If I had tooling and other people in my group had more familiarity with it, I sure as heck would. Holy crap am I sick and tired of being limited to just straight C and a very tiny subset of C++. And 90% of the new stuff in C++ is not targeted at the embedded market (quite the opposite!) where as Ada has stayed closer to its roots.
Nothing in Ada made it impossible to use it on PC or similar devices. And performance of its compiled code was similar to that of C code if not better. And some of its features like ability to return from a function a dynamically-sized stack-allocated array is still not available in C/C++ or Rust for that matter.
I guess what really made it a niche language was the cost of compilers. DoD vendors in eighties already learned how to milk their customer.
I've recently been curious why Ada isn't more popular in industry and academia beyond its niches in avionics and defense. Seems close in speed & memory usage to C/C++, has good GNU tools, and claims resiliance to the pitfalls of C.
I think - please correct me if I'm wrong - that Ada has pretty much the same problems as C if you use manual dynamic memory management. Ada supports Garbage Collection in theory, but it is optional, and I don't think many implementations actually supply a GC. Especially since Ada apparently is often used in realtime systems where dynamic memory management is usually avoided altogether (there is a subset of Ada specifically designed for building realtime software that explicitly prohibits any dynamic memory management).
Ada is - as far as I remember - much safer with regards to buffer overflows and bounds checking. But the bigger problem is probably that far more developers know C than Ada, and that something like an SSL library intended for widespread use needs to work with many different compilers and linkers. If you use GCC, I think it is possible to compile Ada code using the GNU Ada compiler and link it to C code compiled using the GNU C compiler, but I am not sure how things look if you use some other C compiler.
I've never used Ada, and I also don't really do systems stuff, but it does seem like it's a pretty neat language, at least compared to C. From what I have seen, it looks like it has better memory guarantees while still being fast and low-level.
With be the popularity of Rust, it makes me kind of wonder why Ada isn't more popular. I should give the language a go.
There is a reason why Ada continues to be used in safety critical systems--it works. More bugs are prevented and problems are detected earlier than they would be in a more lax language such as C or C++.
The large uptake and excitement around Rust shows that there are many C and C++ programmers who appreciate the safety guarantees that it provides. The popularity of Rust has actually created a resurgence of interest in Ada and each language has benefitted from the other.
For example, Spark, a well-defined subset of the Ada language intended for formal verification of mission-critical software, is adopting safe pointers that were inspired by Rust (source: https://blog.adacore.com/using-pointers-in-spark).
I would not be surprised if Rust also adds features based on ideas from Ada.
This is good. The "fast and loose" qualities of C and C++ allow far too many errors and security vulnerabilities in software. We have better tools. We just need to use them.
Ada was designed a few years before C and it could do much more than C and without the problems you mentioned.
So we don't have to wonder at all, it would have turned out exactly the way it did and the reason is because things like undefined behavior, zero terminated strings, null pointers, etc have positive utility underappreciated by academics.
It's always fun to read peoples drive-by opinions about the only decent language IMO. Ada is highly compatible with C code. For dynamic allocations with "ownership" there is the concept of memory pools which CAN use a GC if thats how you choose to implement the pool allocator.
C/C++ is used over Ada just for familiar syntax. The coding standards used for safety-critical projects limit the features into a tiny safe subset, Essentially DSL.
Linters and code checkers and static analyzers check the code more thoroughly than the compiler does.
For example, all memory is allocated during initialization. No allocation or reallocation from the heap afterward. That's why you see in the weapon specs familiar magic numbers like can track 256 targets simultaneously.
JOINT STRIKE FIGHTER AIR VEHICLE C++ CODING STANDARDS FOR THE SYSTEM DEVELOPMENT AND DEMONSTRATION PROGRAMDocument Number2RDU00001 Rev C December 2005
https://www.stroustrup.com/JSF-AV-rules.pdf
No you shouldn't be writing in Ada. Embedded software running all kinds of sensitive workloads, from pacemakers to routers/switches use C for it's superior tooling, universal support across compilers and chip vendors, massive user base and decades long best practices (like NASA's C coding guidelines) to mitigate some of C's potential inadvertent misuses.
Not to mention the bevy of advanced niche features, like SIMD support, and custom GCC extensions that lend superpowers to C coders that other languages typically lack.
Sure, ada may have it's benefits for certain narrow use cases, but for non-hobby projects spanning tens/hundreds of engineers, considering real world vendor support for ada and missing talent pool, C is the obvious choice
Very cool! I’ve used Ada in my spare time, and it has a lot of good features that I wish C-family languages had (like strong typedefs, no implicit conversions, better ways to do things than passing pointers around, arrays that don't decay into pointers, and types constrained to ranges). It is a lot more complex than C, but it feels a lot easier to read, and while it takes longer to write (for me) than C, it has a lot fewer weird edge cases/quirks to it than C does.
It also seems to have more powerful ways to set the exact machine representation of types than C.
Don't know about Ada, but Rust and ATS can. The Rust code would need to be written in an unsafe block in order to as freely modify memory as C, but regular Rust can still do a lot without requiring automatic memory management, safely.
As you can see from the article (not that you seem to have read any of it), ATS can express C, and optionally prove low-level stuff about it.
I have used Ada in the past, and it is really a great language and quite performant.
I'm convinced that if the Ada designers had gone with a C-like syntax the language would've been more widely adopted and tons of bugs would've been avoided.
As much as I like Ada, there were a couple projects at an old office that were great demonstrations that you could write C code in any language. Among other things, they absolutely failed to understand the type system so had a lot of manual range checks instead of letting the compiler and automatically generated runtime checks do the work for them. They didn't understand how to loop over arrays, passing in size information as a parameter. It was gross code, like someone had simply translated C or Fortran to Ada without consideration of the target language's abilities.
It would be like someone choosing Rust and then making everything unsafe. Or Haskell (I saw this in a tutorial once, it was hilarious and disgusting at the same time) and using strings (data) for dispatch instead of translating them into types and actually exercising the type system.
All that is to say, thoughtless programmers outnumber thoughtful ones. The language can only take you so far.
I think that an ada-like language could make a real resurgence in embedded programming. Ada gets all the things about bare-metal right that C got wrong. However, it's held up by legacy tooling, clunky syntax, and obtuse compiler errors. Adacore has gone a long way towards alleviating those issues over the last few years, with alire and the ada_language_server. Time will see where this language takes us.
Behold, LLVM and GCC both miscompile the same numerical code involving mildly tricky aliasing constraints. https://github.com/rust-lang/rust/issues/54878#issuecomment-...
I think I'd prefer that safety-critical code be written in languages that don't allow pointer arithmetic except in scenarios that can be proved via static analysis not to introduce multiple memory aliases. Expecting program writers and compiler authors to get these sorts of things right in C/C++ is just unreasonable.
reply