C++ im Vergleich zu ZIG


  1. Einleitung

Einleitung

Seit 20 Jahren begleitet mich C++ und stellt für mich “die beste Sprache” dar. Und der Grund dafür ist einfach:
C++ kann C Code ohne Zwischenschritte nutzen und produzieren.

Jede Zeile C Code ist gültiger C++ Code und jede mit
extern "C" eingeleitete Zeile in C++ produziert C Funktionen, die mit C++ Mitteln implementiert sind.

Eine bessere Integration gibt es nicht … zumindest gab es sie nicht bis ZIG auftauchte.

ZIG kann C Code ebenfalls direkt inkludieren und nutzen, während mit extern markierte Funktionen wieder von C Code angesprungen werden können.

Hello World

1//C++
2#include <cstdio>
3
4int main()
5{ // main program entry point
6  printf("Hello %s\n", "World");
7  return 0;
8}
1//ZIG
2const std = @import("std");
3
4pub fn main() u8 {
5  // main program entry point
6  std.debug.print("Hello {s}\n", .{ "World" });
7  return 0;
8}
  • @import() lädt eigene Module oder Elemente der Standard Bibliothek.
  • Der Inhalt eines importierten Moduls ist ein Typ (quasi ein struct).
  • const mytupel = .{ value1, value2 } erzeugt ein Tupel mit den Typen der übergebenen Werte.

Funktionen und Parameter

 1//C++
 2#include <cstdio>
 3
 4static double add(int const a, float const b)
 5{ // local private function
 6  auto d = static_cast<double>(a);
 7  d += b;
 8  return d;
 9}
10
11void run_add()
12{ // public function
13  double const d = add(12, 34.0f);
14  printf("%e\n", d);
15}
 1//ZIG
 2const std = @import("std");
 3
 4fn add(a: i32, b: f32) f64 {
 5  // local private function
 6  var d = @as(f64, @floatFromInt(a));
 7  d += b;
 8  return d;
 9}
10
11pub fn run_add() void {
12  // public function
13  const d: f64 = add(12, 34.0);
14  std.debug.print("{e}\n", .{ d });
15}
  • Variablen werden mit var x = ... deklariert, Konstanten mit const x = ...
  • Der Typ wird automatisch von der Zuweisung abgeleitet, oder explizit angegeben const x: type = ...
  • Explizite Casts finden mit @as(type, expression) statt.
  • Funktionsparameter sind in ZIG automatisch const und können in der Funktion nicht verändert werden.

Optionale Werte

C++17 führt mit std::optional<T> die Möglichkeit ein, Variablen als “leer” oder befüllt zu unterscheiden. In ZIG sind “Optionals” Teil der Kernsprache und werden mit ? identifiziert.

 1//C++
 2#include <optional>
 3
 4static std::optional<int> add_opt(std::optional<int> const& a, int b)
 5{
 6  if(a)
 7  {
 8    auto value = *a;
 9    return value + b;
10  }
11  else
12  {
13    return std::nullopt;
14  }
15}
16
17void run_add_opt()
18{
19  auto value1 = add_opt(12, 34);
20  printf("value1=%d\n", *value1);
21  auto value2 = add_opt(std::nullopt, 34);
22  if(!value2.has_value())
23  {
24    printf("value2 has no value\n");
25  }
26}
 1//ZIG
 2const std = @import("std");
 3
 4fn add_opt(a: ?i32, b: i32) ?i32 {
 5  if(a) |value| {
 6    return value + b;
 7  }
 8  else {
 9    return null;
10  }
11}
12
13pub fn run_add_opt() void {
14  const value1 = add_opt(12, 34);
15  std.debug.print("value1={d}\n", .{ value1.? });
16  const value2 = add_opt(null, 34);
17  if(value2 == null) {
18    std.debug.print("value2 has no value\n", .{ });
19  }
20}

Fortsetzung folgt