Die Programmiersprache C3
(c3-lang.org)- Eine weiterentwickelte Sprache, die Syntax und Semantik von C übernimmt und zugleich Sicherheit und Benutzerfreundlichkeit verbessert, sodass die gewohnte Umgebung für bestehende C-Entwickler erhalten bleibt
- Bietet vollständige C-ABI-Kompatibilität und kann daher direkt in C/C++-Projekte integriert werden; es gibt einen Fall, in dem Teile von vkQuake nach C3 konvertiert und mit dem Compiler
c3cgebaut wurden - Verbessert Codestruktur und Ausdruckskraft durch Modulsystem, Operator Overloading und Compile-Time-Makros
- Enthält moderne Funktionen wie vertragsbasierte Programmierung (Gradual Contracts), Zero-Overhead-Fehlerbehandlung sowie Runtime- und Compile-Time-Reflection
- Stellt im Debug-Modus automatisch Sicherheitsprüfungen und detaillierte Stacktraces bereit, was bei Fehlererkennung und Stabilität vorteilhaft ist
Überblick über C3
- C3 ist eine Programmiersprache, die auf Syntax und Semantik der Sprache C aufbaut und diese weiterentwickelt
- Ziel ist es, die vertraute Form für bestehende C-Programmierer beizubehalten und die Sprache zugleich weiterzuentwickeln
- Unterstützt präzises und zweckgerichtetes Operator Overloading
- Ohne die komplexe Overloading-Struktur von C++ lassen sich Vektor-, Matrix- und Fixed-Point-Berechnungen natürlich ausdrücken
- Unterstützt vertragsbasierte Programmierung, sodass sich Einschränkungen zur Laufzeit und zur Compile-Zeit explizit angeben lassen
- Das stärkt die Stabilität des Codes und die Konsistenz der Spezifikation
- Kombiniert die Vorteile von Result-basierter Fehlerbehandlung und Exceptions
- Bietet eine Struktur für Fehlermanagement, die sich natürlich in C-Code integriert
- Unterstützt Type Introspection sowohl zur Compile-Zeit als auch zur Laufzeit
- Inline-Assembly: ohne Strings oder komplexe Constraints lässt sich Assembly wie normaler Code schreiben
- Im Debug-Modus werden zur Laufzeit automatisch Bounds Checks und Value Checks eingefügt
- Die C3-Standardbibliothek bietet in Debug-Builds standardmäßig detaillierte Stacktraces
- Statt eines schlichten „segmentation fault“ lässt sich die genaue Fehlerstelle erkennen
Ergonomics and Safety
- Optionals sorgen für sichere Fehler- und Null-Behandlung
- Die
defer-Syntax unterstützt die Automatisierung der Ressourcenfreigabe - Mit slices und foreach ist sichere Iteration möglich
- Mit kommentarbasierten contracts lassen sich Code-Einschränkungen explizit festlegen
- Im
@pool-Kontext wird automatische Speicherfreigabe unterstützt
Performance by default
- Durch direkt geschriebene SIMD-Vektoren ist Kontrolle auf Hardware-Ebene möglich
- Die Auswahl verschiedener Memory Allocators unterstützt feine Performance-Abstimmung
- Für die Fehlerbehandlung wird ein overheadfreies Design verwendet
- Schnelle Compile-Zeiten und Optimierungen des LLVM-Backends werden genutzt
- Bietet einfach nutzbare Inline-Assembly
Batteries included standard library
- Bietet Standarddatenstrukturen einschließlich dynamischer Container und Strings
- Sichert durch Cross-Platform-Abstraktion Portabilität zwischen Plattformen
- Erlaubt bei Bedarf nativen Plattformzugriff
Leverage existing C or C++ libraries
- C3 ist vollständig kompatibel zur C ABI, daher sind keine separaten „C-kompatiblen Typen“ oder Funktionsdeklarationen erforderlich
- C-Code kann in C3 gelinkt werden, und C3-Code kann auch in C gelinkt werden
Modules are simple
- Ein einfaches und intuitives Modulsystem
- Die Voreinstellungen sind sinnvoll gewählt und behindern den Entwicklungsfluss nicht
- Bietet Namespace-Verwaltung über Module
- Vereinfacht durch explizite Kontrolle die Kapselungsstruktur
- Über Interfaces lassen sich gemeinsame Verhaltensweisen definieren
- Bietet generic modules, mit denen sich generische Typen einfach und klar umsetzen lassen
- Unterstützt Strukturwiederverwendung durch Struct-Subtyping
Macros without a PhD
- Compile-Time-Makros lassen sich in einer Form schreiben, die gewöhnlichen Funktionen ähnelt
- Unterstützt typbewusste Makros, die Typinformationen des Codes verstehen
- Bietet klarere und leistungsfähigere Codegenerierung als der Präprozessor von C
4 Kommentare
Da kommt ja einiges heraus. LONG LIVE C-LANG !!!
Aber wenn später einmal C4 erscheint, wird es dann geradezu explosionsartig populär sein ...
Da Zig jedes Jahr Breaking Changes mitbringt, gefällt mir die Sprache zwar, aber inzwischen greife ich nicht mehr danach.
Andererseits wirkt C3 nach allem, was ich in der Einführung gesehen habe, insgesamt wie eine Mischung aus C + Go, also angenehm zu lesen und zu schreiben, und es scheint deutlich weniger Stress durch Versions-Updates zu geben.
Ich unterstütze es auch ein bisschen ... ich benutze es in letzter Zeit, und es macht Spaß.
Mir gefällt, dass es sich anfühlt, als würde es nur die unbequemen Punkte von C verbessern wollen.
Die offizielle Dokumentation ist noch nicht ganz ausgereift
(wenn man verschiedene Funktionen nachschlagen will, sind die Beschreibungen oft an völlig unerwarteten Stellen zu finden ...)
Hacker-News-Kommentare
Es erzwingt weder ein neues Speichermodell noch versucht es, zu C++ zu werden
Vor allem sorgt die vollständige ABI-Kompatibilität dafür, dass man C3-Dateien direkt in bestehende C-Build-Systeme mischen kann, ohne Bindings schreiben zu müssen
Ich applaudieren der Vision des Maintainers, der eher auf Evolution als auf Revolution setzt
Als Sprache zum Lernen am Wochenende kann man sie gut empfehlen. Sie wirkt moderner als C99, fühlt sich aber vertraut an
Dass ich C nie ganz aufgeben kann, liegt an cstring und nicht freigegebenen Zeigern
Nicht C selbst ist die gefährliche Sprache, sondern Implementierungen und ABIs sind gefährlich
Mit fat pointers, Verbesserungen bei varargs, UBSan, MTE und Ähnlichem wird es eigentlich ganz brauchbar
Wenn der Compiler Verträge nicht zwingend prüfen muss und ein Verstoß zu undefiniertem Verhalten führen kann, weiß ich nicht, wie man das verlässlich einsetzen soll
Eine tolle Funktion, aber sie wirkt etwas riskant
Man kann sie ignorieren, zur Laufzeit prüfen oder sie stets als wahr annehmen und für Optimierungen nutzen
Zum Beispiel kann man die Gültigkeit eines Zeigers prüfen, eine Bedingung wie „Eingabe muss ungerade sein“ aber nur als Annahme behandeln
Große Teams können sie erzwingen, und Tools wie Visual Studio können auch nur Warnungen anzeigen, sodass man sich schrittweise daran gewöhnen kann
assertgeprüftDas heißt: während der Entwicklung einschalten und bei der Auslieferung abschalten, damit die Performance nicht leidet
Bedingungen, die unbedingt geprüft werden müssen, sollte man innerhalb der Funktion direkt im Code behandeln
Unterschiede zu C sind unter anderem: keine Header-Dateien, modulbasierte Namespaces, Slices, Operator Overloading, generische Module, Result-basierte Fehlerbehandlung und Laufzeitprüfungen im Sicherheitsmodus
Mir persönlich fehlen Function Overloading, Standardparameter und Tuple-Rückgaben
ResultoderExpectedin C3 als Optional bezeichnet werdenGemeint sein sollte nicht „T oder leer“, sondern „T oder E“, daher scheint der Name unpassend
Link zur relevanten Dokumentation
Option<T>nochResult<T, E>Der Fehlertyp ist auf einen einzelnen Integer-Code beschränkt, was gut zur Philosophie „Evolution, nicht Revolution“ passt
Auch die Syntax
type?ist intuitivDas Design bewahrt die Bedeutung von C und reduziert gleichzeitig die Last von out param
Resulthat bereits die allgemeine Bedeutung eines Rückgabewerts und könnte deshalb verwirrenYouTube-Playlist
Beeindruckend fand ich, dass diese drei Sprachen eher ihre Trade-offs miteinander teilen und voneinander lernen, statt einfach nur zu konkurrieren
Stattdessen kommen Funktionen wie Makros und Reflection hinzu
Sie belegen so viel Speicher wie der größte Typ, und durch Runtime-Typprüfungen verlagert sich der Kontrollfluss, wodurch Vorteile statischer Typsysteme verloren gehen
Wenn man sie braucht, ist es besser, sie direkt selbst zu implementieren
Ich habe in C selbst Generics, Slices und Fehlerweitergabe implementiert, aber einen Compiler zu bauen ist zu komplex
Deshalb nutze ich parallel eine C-Variante und Go
Die Einstiegshürde ist so niedrig, dass man an einem einzigen Tag einen Prototypen bauen kann
Es ist der einzige Weg, ein neues Paradigma in die Realität umzusetzen
Eine Sprache ist schwierig, weil man Syntax, Standardbibliothek, Tooling und Runtime aufeinander abstimmen muss, aber gerade deshalb hat sie so großen Einfluss auf die Zukunft
Dank LLVM konnte er selbst einen neuen Compiler bauen
Eine allein genutzte C-Variante ist in Ordnung, aber sobald man mit anderen zusammenarbeitet oder externe Bibliotheken nutzt, braucht man eine gemeinsame Sprache
Und dass Ausnahmen „Excuses“ genannt werden, ist irgendwie niedlich und clever
Besonders der Discord-Link in der Navigation hat diesen Eindruck noch verstärkt