Ada Compared with C, C++, Java, Rust & Python
Map Ada concepts to other languages (packages vs headers/modules, tagged types vs classes, generics vs templates, tasks vs threads, access types vs pointers/references, exceptions, contracts), understand overflow and integer-division semantics, and know where Ada is the right tool.
Knowing how Ada features correspond to those in languages you already know speeds up learning and helps in interviews and mixed-language projects. Ada often provides the same capability with more compile-time checking and more explicit syntax.
Concept Map
Approximate correspondences; semantics differ in details.
• Packages ≈ modules with enforced spec/body separation. • Tagged types ≈ classes; interfaces ≈ traits/interfaces. • Generics are contract-checked before instantiation. • Tasks/protected objects are language-level concurrency.
Ada C / C++ Java / C# Rust
package spec / body .h / .c(pp), namespaces class files, modules modules, crates
private type opaque struct / private private fields pub/priv struct
type X is new Integer typedef (no new type!) — newtype pattern
subtype with range — — —
tagged type + T'Class class + virtual class trait objects
interface abstract class interface trait
generic (contract checked) template (duck typed) generics (erased) generics + traits
access type pointer reference Box / & / Rc
limited type deleted copy ctor — non-Copy type
controlled type RAII destructor try-with-resources Drop
task / protected object std::thread / mutex Thread / synchronized std::thread / Mutex
exceptions exceptions (C++) exceptions Result / panic
Pre / Post / predicates assert / C++26 contracts — deb
…Semantics that Differ
Integer overflow: undefined in C, wrapping in Java/C#, panic in Rust debug builds and wrapping in release; in Ada, Constraint_Error always (unless you choose a modular type, where wrap-around is defined). Division truncates toward zero, as in C and Java, but Ada has both mod (sign of the divisor, like Python's %) and rem (sign of the dividend, like C's %). Arrays know their bounds, and indexing is always checked. Strings are fixed-length arrays of characters, not NUL-terminated. There are no implicit numeric conversions. Parameters use modes rather than value/reference/pointer distinctions. Memory safety comes from checks and restrictions rather than a borrow checker (though SPARK adds ownership).
Overflow, modular wrap-around, arrays with bounds, and division semantics. Output: Modular Word'Last + 1 = 0 (defined wrap-around) Integer'Last + 1 -> Constraint_Error (no silent overflow) Sum of "ABC" codes = 198, length known: 3 7 / 2 = 3, -7 / 2 =-3, -7 mod 2 = 1, -7 rem 2 =-1
• Overflow → Constraint_Error; modular types wrap by definition. • mod follows the divisor's sign (like Python %), rem the dividend's (like C %). • Checked arrays with bounds; no implicit conversions.
with Ada.Text_IO; use Ada.Text_IO;
procedure L67_Compare is
-- C: int x = INT_MAX; x++; -> undefined behavior
-- Java/C#: wraps silently to MIN_VALUE
-- Ada: Constraint_Error, or explicit wrap-around with a modular type
type Word is mod 2 ** 32;
W : Word := Word'Last;
I : Integer := Integer'Last;
-- C: arrays decay to pointers and lose their length
-- Ada: arrays carry their bounds
function Sum (A : String) return Natural is
Total : Natural := 0;
begin
for C of A loop
Total := Total + Character'Pos (C);
end loop;
return Total;
end Sum;
-- Python/JS: 1 + "1" -> error at run time / "11"
-- Ada: mixing types is a compile-time error (see the idioms lesson)
begin
W := W + 1;
Put_Line ("Modular Word'Last + 1 =" & Word'Image (W) & " (defined wrap-around)");
begin
I := I + 1;
exception
when Constraint_Error => Put_Line ("Integer'Last + 1 -> Constraint_Error (no silent overflow)");
end;
Put_Line ("Sum of ""ABC"" codes =" & Natural'Image (Sum ("ABC")) & ", length known:" & Integer'Image (String'("ABC")'Length));
Put_Line ("7 / 2 =" & Integer'Image (7 / 2) & ", -7 / 2 ="
…When to Choose Ada
Ada shines where correctness, longevity and predictability matter: avionics, rail, space, defense, medical devices, industrial control, and security-critical components (often with SPARK). Its readability suits code that lives for decades and is maintained by changing teams. Trade-offs: a smaller ecosystem than C++, Java or Python (improving with Alire), more verbose syntax, and fewer developers on the job market — which also makes Ada skills valuable in its niches.
• Strengths: safety, long-lived code, real-time, formal proof. • Trade-offs: ecosystem size, verbosity, hiring pool.
-- assuming (-7) mod 2 = -1 as in C -- (-7) mod 2 = 1; (-7) rem 2 = -1
Ada's mod follows the sign of the divisor (verified output).
subtype Meters is Float; -- expecting type safety like a C typedef type Meters is new Float;
A subtype is compatible with its base type; a derived type is a distinct type.
-- translating C code line by line, using access types for everything -- use in out parameters, unconstrained arrays and containers
Idiomatic Ada needs far fewer pointers than C.
What is Integer'Last + 1 in Ada (checks on)? A. Integer'First B. Undefined C. Constraint_Error D. 0
Which Ada operator behaves like C's % for negative numbers? A. mod B. rem C. / D. abs
What corresponds most closely to a Rust trait? A. package B. interface C. task D. subtype
Which Ada feature is like C++ RAII destructors? A. Controlled types (Finalize) B. Limited types C. Protected objects D. Generics Trace the comparison example.
Real output: Modular Word'Last + 1 = 0 (defined wrap-around) Integer'Last + 1 -> Constraint_Error (no silent overflow) Sum of "ABC" codes = 198, length known: 3 7 / 2 = 3, -7 / 2 =-3, -7 mod 2 = 1, -7 rem 2 =-1
with Ada.Text_IO; use Ada.Text_IO;
procedure L67_Compare is
-- C: int x = INT_MAX; x++; -> undefined behavior
-- Java/C#: wraps silently to MIN_VALUE
-- Ada: Constraint_Error, or explicit wrap-around with a modular type
type Word is mod 2 ** 32;
W : Word := Word'Last;
I : Integer := Integer'Last;
-- C: arrays decay to pointers and lose their length
-- Ada: arrays carry their bounds
function Sum (A : String) return Natural is
Total : Natural := 0;
begin
for C of A loop
Total := Total + Character'Pos (C);
end loop;
return Total;
end Sum;
-- Python/JS: 1 + "1" -> error at run time / "11"
-- Ada: mixing types is a compile-time error (see the idioms lesson)
begin
W := W + 1;
Put_Line ("Modular Word'Last + 1 =" & Word'Image (W) & " (defined wrap-around)");
begin
I := I + 1;
exception
when Constraint_Error => Put_Line ("Integer'Last + 1 -> Constraint_Error (no silent overflow)");
end;
Put_Line ("Sum of ""ABC"" codes =" & Natural'Image (Sum ("ABC")) & ", length known:" & Integer'Image (String'("ABC")'Length));
Put_Line ("7 / 2 =" & Integer'Image (7 / 2) & ", -7 / 2 ="
…