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 ="
…