I have a passing acquaintance with both, and I'm almost certain both would have caught the three bugs listed on that page.
I have a passing acquaintance with both, and I'm almost certain both would have caught the three bugs listed on that page.
A lot of the static analyses we've looked into (and I'm hoping for more detailed blog posts about that in the future) find plenty of bugs, but also find lots of non-bugs. Combine that with being too slow to run during the normal build, and you can't break the build when such a bug is found.
I think one of the most interesting aspects of this is how we catch the bugs early, and force developers to fix them immediately by breaking the build.
We still develop using GCC - for our use case Clang performance isn't there yet - but have our continuous integration system perform Clang builds (as well as other platform/compiler variants, with unit+regression tests, etc.) so we miss out on the immediate build breakage that you mention, but do find out within ~30 mins if someone slipped up.
Plus the compiled code is pretty fast. So if you're feeling the need to reduce your workload take a look at it, you might be surprised.
However, there is a small collection of oss Ada libraries out there.
Anyway, Ada has some other amazingly cool features. The concurrency primitives it offers are very cool, lets you make some much stronger guarantees about the interactions between threads than any other language I've seen. For example, you can define rendezvous sections, which if memory serves, are pieces of code that are guaranteed to only be run once both threads participating in the rendezvous and neither thread can leave the section until both are ready.
You're right about the concurrency. Ada has a bunch of stuff like that built into the language since 1983.
The particularly cool toys I like are SPARK (a formal verifier tool) and stackcheck - tells you exactly how deep in the stack your code can possibly go. (Yes you have to annotate cycles.)
Take a look again, with an eye towards large scale long lived critical systems. You'll find that explicitness a feature, as is the very strict static typing.
Oh, and they got pointers right the first time.
EDIT: Forgot to mention the coolness of the type system - you can declare ranges and other type information and the compiler will hold that requirement strictly. for example type direction is range 0..359; Declares the obvious, but now you can have the compiler error if you assign a direction type with a value that might be outside that range. Even if you don't set that option you can always use the foo'valid attribute to check that foo is within bounds. This is used to check for stray cosmic radiation (seriously!).
Yes it seems like overkill. But when you come back to 20 year old code that's still running you'll smile.