C ist am besten (2025)
(sqlite.org)- SQLite ist seit 2000 eine leichtgewichtige Datenbank-Engine, die in C implementiert ist, und es gibt keine Pläne, sie in einer anderen Sprache neu zu schreiben
- C wird für SQLite als die am besten geeignete Sprache in Bezug auf Leistung, Kompatibilität, minimale Abhängigkeiten und Stabilität angesehen
- Objektorientierte Sprachen (C++, Java usw.) haben große Einschränkungen bei sprachübergreifenden Aufrufen, während ein prozeduraler Ansatz sogar einfacher und schneller sein kann
- „Sichere Sprachen“ wie Rust oder Go sind noch nicht ausgereift und passen nicht zu der Qualitätsstrategie von SQLite (z. B. 100% Branch-Tests, OOM-Wiederherstellung)
- Die Möglichkeit einer zukünftigen Portierung nach Rust bleibt offen, aber dafür müssten verschiedene Bedingungen wie Reifegrad, Kompatibilität, Leistung und Tool-Unterstützung erfüllt sein
1. Warum C die beste Wahl ist
- SQLite wurde am 29. Mai 2000 von Anfang an in standardkonformem C implementiert, und bis heute gibt es keine Pläne, auf eine andere Sprache umzusteigen
- Als Gründe, warum C für die Implementierung von SQLite geeignet ist, werden Leistung, Kompatibilität, geringe Abhängigkeiten und Stabilität genannt
1.1 Leistung
- SQLite ist eine intensiv genutzte Low-Level-Bibliothek, für die hohe Geschwindigkeit essenziell ist
- Als Beispiele wird die Leistung in den Dokumenten „Internal Versus External BLOBs“ und „35% Faster Than The Filesystem“ belegt
- C wird oft als „portable Assemblersprache“ bezeichnet, weil es hardwarenahe Kontrolle bietet und zugleich Portabilität zwischen Plattformen wahrt
- Andere Sprachen behaupten zwar, „so schnell wie C“ zu sein, aber keine Sprache behauptet, schneller als C zu sein
1.2 Kompatibilität
- Nahezu jedes System bietet die Möglichkeit, in C geschriebene Bibliotheken aufzurufen
- Android kann SQLite beispielsweise aus Java-Anwendungen über einen Adapter aufrufen
- Wäre SQLite in Java geschrieben worden, wäre es in Objective-C- oder Swift-basierten iPhone-Apps nicht nutzbar gewesen
1.3 Geringe Abhängigkeiten
- In C geschriebene Bibliotheken haben sehr wenige Laufzeitabhängigkeiten
- In der Minimal-Konfiguration benötigt SQLite nur die folgenden Funktionen aus der Standard-C-Bibliothek
- memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp()
- Selbst beim vollständigen Build werden im Wesentlichen nur malloc(), free() und Datei-E/A verwendet
- Moderne Sprachen dagegen verlangen oft Laufzeitumgebungen von mehreren MB Größe und Tausende von Schnittstellen
1.4 Stabilität
- C ist eine alte Sprache mit wenigen Veränderungen, die klares und vorhersehbares Verhalten bietet
- Bei der Entwicklung einer kleinen, schnellen und zuverlässigen Datenbank-Engine wie SQLite ist es wichtig, dass sich die Sprachspezifikation nicht ständig ändert
2. Warum es nicht in einer objektorientierten Sprache geschrieben wurde
-
Manche Entwickler glauben, komplexe Systeme ließen sich nur in objektorientierten Sprachen implementieren, aber für SQLite trifft das nicht zu
-
In C++ oder Java geschriebene Bibliotheken können in der Regel nur von Anwendungen verwendet werden, die in derselben Sprache geschrieben sind
- C-Bibliotheken dagegen lassen sich aus fast jeder Sprache aufrufen
-
Objektorientierung ist ein Designmuster und nicht die Sprache selbst; auch in C lassen sich objektorientierte Strukturen umsetzen
-
Objektorientierung ist nicht immer die beste Wahl, und prozeduraler Code kann einfacher sowie bei Wartbarkeit und Leistung vorteilhafter sein
-
In der Frühphase der SQLite-Entwicklung (Anfang der 2000er) war Java noch unreif, und bei C++ gab es schwere Kompatibilitätsprobleme zwischen Compilern
- Damals war C eindeutig die bessere Wahl, und auch heute gibt es kaum Vorteile einer Neuschreibung
3. Warum es nicht in einer „sicheren Sprache“ geschrieben wurde
- In jüngerer Zeit haben „sichere Sprachen“ wie Rust und Go viel Aufmerksamkeit bekommen, doch SQLite bleibt weiterhin bei C
- In den ersten zehn Jahren von SQLite gab es noch keine sicheren Sprachen
- Eine Neuschreibung in Go oder Rust wäre zwar möglich, würde aber das Risiko neuer Bugs und geringerer Geschwindigkeit mit sich bringen
- Sichere Sprachen fügen zusätzliche Branches wie Array-Grenzprüfungen ein
- In korrektem Code werden diese Branches nicht ausgeführt, wodurch 100% Branch-Tests unmöglich werden
- Die meisten sicheren Sprachen beenden Programme bei Speichermangel (OOM)
- SQLite ist jedoch so entworfen, dass es sich auch bei OOM korrekt erholt, was mit diesem Verhalten kollidiert
- Bestehende sichere Sprachen sind allesamt neu und befinden sich in schneller Veränderung
- SQLite bevorzugt alte und stabile Sprachen
4. Möglichkeit einer Portierung nach Rust
- Es besteht die Möglichkeit, SQLite in Rust neu zu schreiben, aber eine Portierung nach Go ist nahezu unmöglich
- Grund: Go mag
assert()nicht
- Grund: Go mag
- Voraussetzungen für eine Portierung nach Rust
- Rust müsste reifer werden und sich langsamer verändern, um zu einer „alten und stabilen Sprache“ zu werden
- Rust müsste universell nutzbare Bibliotheken erzeugen können, die aus allen Sprachen aufrufbar sind
- Rust müsste Objektcode erzeugen können, der auch auf Embedded-Geräten ohne Betriebssystem läuft
- Es müsste ein Tooling-Ökosystem geben, das Tests mit 100% Branch-Coverage unterstützt
- Rust müsste Mechanismen zur OOM-Wiederherstellung bereitstellen
- Es müsste nachgewiesen werden, dass eine Implementierung ohne Leistungsverlust auf C-Niveau möglich ist
- Entwickler, die glauben, dass Rust diese Bedingungen erfüllt, können das SQLite-Team direkt kontaktieren und darüber diskutieren
5. Fazit
- SQLite ist eine kleine, schnelle und zuverlässige Datenbank-Engine, und die Eigenschaften der Sprache C passen zu diesem Ziel
- Ein Wechsel zu einer objektorientierten oder sicheren Sprache bringt hinsichtlich Kompatibilität, Leistung und Qualitätskontrolle keinen praktischen Nutzen
- Die Einfachheit und Stabilität von C tragen die langfristige Wartbarkeit und Zuverlässigkeit von SQLite
8 Kommentare
Ist doch ohnehin ein Projekt, das keine PRs annimmt, also na ja ... sie verwenden einfach das, was sie selbst benutzen wollen.
Wenn es auf Kompaktheit ankommt, gibt es keine Sprache, die C, C++ oder Rust ersetzen könnte. Nur gibt es wohl nicht viele Entwickler, die nachvollziehen können, Software mit Sorge vor bitweisen Overflows oder Hacks in Strukturen oder Maps zu entwickeln.
Der Titel ist viel zu reißerisch. Wenn ihr den Originalbeitrag lest, seht ihr, dass es darin darum geht, warum C für die Entwicklung von sqlite am besten geeignet ist. Beruhigt euch bitte alle.
Nein, sogar der Artikel selbst wurde schon vor 7 Jahren geschrieben? Es wirkt, als wäre er durch spätere Ergänzungen im Jahr 2025 teilweise aktualisiert worden … 🤦
Wichtig ist, in unterschiedlichen Entwicklungssituationen die passende Sprache zu verwenden und diese Entscheidung treffen zu können; so einen Titel zu setzen, als wäre eine bestimmte Sprache immer gut, ist ein Denk-Niveau auf Hauptschulabschluss...
Ich denke, der größte Vorteil von C liegt darin, dass es direkt das Wesen berührt, dass „Computer Bitfolgen sind“. Der Reiz von C liegt in seiner einfachen Philosophie und dem radikalen
reinterpret casting, durch das man als Nutzer fast immer abschätzen kann, in welchen Maschinencode etwas übersetzt wird. Nicht weil es C ist, kann es von allen Sprachen aufgerufen werden, sondern weil das ABI aufrufbar ist, und in C lediglich vorhersagbar ist – oder sein muss –, welche Bitfolgen Ein- und Ausgabe darstellen. Auch wenn man über Implementierbarkeit diskutiert, halte ich die Unterscheidung für wichtig, ob etwas auf einer Turing-Maschine unmöglich ist oder nur in der gerade verwendeten Sprache oder dem Framework unmöglich ist.Hacker-News-Kommentare
Ich finde nicht, dass jedes Projekt oder jeder Programmierer es extra rechtfertigen muss, nicht Rust oder Zig zu verwenden.
Auf Hacker News und anderen Plattformen gibt es die Tendenz, diese Sprachen übermäßig zu pushen.
Wenn man mit C bereits gute Ergebnisse erzielt und die Nutzer zufrieden sind, gibt es keinen Grund, dass Außenstehende sich einmischen.
Dass sich Menschen, die an technologischem Fortschritt interessiert sind, mit dem Potenzial neuer Sprachen beschäftigen, ist ein natürlicher Verlauf.
Außenstehende dürfen natürlich ihre Meinung sagen, aber ein Projekt ist nicht verpflichtet, darauf zu hören.
Rust verringert zwar die Sichtbarkeit von Bugs, aber dieselben Arten von Bugs existieren weiterhin.
C-Entwickler reagieren tendenziell sensibler auf Race Conditions, während bei Rust die Gefahr besteht, sich zu sehr auf das Etikett „sicher“ zu verlassen.
Außerdem sind Korrekturen in Rust nicht immer einfach, wodurch der Refactoring-Aufwand größer werden kann.
Rust ist letztlich eine interessante Sprache, aber kein Allheilmittel und sollte nicht aufgezwungen werden.
Sprachen wie Rust oder Zig haben die Absicht, traditionelle objektorientierte Muster hinter sich zu lassen.
OOP war einmal als konzeptioneller Rahmen attraktiv und konnte ein Gefühl von „Erleuchtung“ vermitteln, erhöht in der Praxis aber oft die Komplexität und schadet der Modularität.
So wie man selbstverständlich eher einen Akkubohrer als einen Handbohrer benutzt, ist es natürlich, ein besseres Werkzeug zu verwenden, wenn es eines gibt.
Es braucht aber auch ausreichend weiterentwickelte Werkzeuge und Ausbildung, um sicheren C-Code schreiben zu können.
Ich bin ein ziemlich ernsthafter Rustacean, halte es aber nicht für vernünftig, jedes Projekt in Rust neu zu schreiben.
Wenn man ein bereits gut validiertes C-Projekt nach Rust überführt, ist kurzfristig eher mit mehr Bugs zu rechnen.
Manche wagen sich dennoch an ein Rewrite in Rust, zum Beispiel Limbo: ein vollständiges Rewrite von SQLite in Rust.
Einer der Hauptvorteile von SQLite ist gerade, dass mehrere Prozesse gleichzeitig darauf zugreifen können; fällt das weg, wird der Einsatzbereich deutlich kleiner.
Sie können einfach selbst eine neue Version bauen und experimentell prüfen, ob sie erfolgreich ist.
Ich habe Erfahrung damit, RediSearch nach Rust zu migrieren.
Der Grund waren die vielen jüngsten CVE-Schwachstellen.
Wenn SQLite solche Probleme nicht hat, ist der Grund für eine Migration zu Rust schwach.
Es scheint Jahrzehnte zu brauchen, um die Stärken und Grenzen von Rust wirklich zu verstehen.
Gerade bei GUI-Anwendungen ist der Nutzen von Rust noch unklar.
Damit Rust ein ähnliches Vertrauensniveau erreicht, muss es vielleicht erst 2040 werden.
Wie Linus erwähnt hat, braucht Rust einen OOM-(Out of Memory)-Recovery-Mechanismus.
Näheres dazu findet sich im LKML-Diskussionslink.
mallocnicht direkt auf.In Embedded- oder Kernel-Code kann man die Allokationsfunktionen sogar vollständig abschalten.
Das heißt, Rust gibt die Kontrolle über den Speicher bereits vollständig.
Die Behauptung „Es gibt keine schnellere allgemeine Sprache als C“ ist ein verkürzter Vergleich, der die Zeit der Entwickler ignoriert.
Statt 5 Stunden mit C für ein Programm zu brauchen, das 4 Sekunden läuft, kann es realistischer sein, in einer anderen Sprache in 5 Minuten eines zu bauen, das 5 Sekunden braucht.
Je mehr Nutzer es gibt, desto größer ist der kumulierte Wert selbst kleiner Geschwindigkeitsunterschiede.
Rust ist noch weit davon entfernt, eine „langweilige und stabile“ Sprache zu sein.
Während C von einem konservativen Komitee verwaltet wird, das Kompatibilität strikt wahrt, gibt Rust zur Problemlösung eher Innovation den Vorrang vor Kompatibilität.
Code aus älteren Versionen lässt sich weiterhin mit neuen Compilern bauen.
Ich halte das für besser, als wie C++ weiterhin alte Features mit sich herumzutragen.
Dagegen haben von Komitees entworfene Sprachen wie C++ oder Common Lisp an Komplexität gewonnen.
Auch Rust ist groß, daher sollte man es für Embedded- oder Kernsysteme mit Bedacht einsetzen.
Ich kann der Haltung „Was gut funktioniert, sollte man nicht unnötig kaputtmachen“ zustimmen.
Die Geschichte der Sprachentwicklung wirkt wie eine Wiederholung des Musters, beim Lösen von Problemen neue Komplexität zu schaffen.
C ist ein Paradebeispiel für die Philosophie „Worse is Better“ und war gerade dank seiner Einfachheit jahrzehntelang erfolgreich.
Rust strebt dagegen nach dem „Right Thing™“.
Da die Last direkter Implementierung in den meisten heutigen Umgebungen gesunken ist, kann es inzwischen die bessere Wahl sein.
Es gibt aber keinen Grund, bereits erfolgreiche Projekte zwanghaft zu migrieren.
Für neue Projekte ist Rust wahrscheinlich häufiger die bessere Wahl.
Einfachheit und Stabilität von C sind unterschätzte Vorteile.
Ich denke, es ist besser, statt die Sprache selbst ständig zu verändern lieber die Standardbibliothek oder das Ökosystem zu verbessern.
Nicht nur Einfachheit, sondern auch die Garantie deterministischen Verhaltens ist wichtig.
Zum Beispiel gefallen mir Funktionen wie designated initializer, compound literal, alignas und memset_explicit.
Persönlich halte ich C immer noch für das Beste.
Rust hat viele gute Ideen, ist aber auch eine Sprache mit klaren Nachteilen.
Noch immer ist die Atmosphäre so, dass sich über Rusts Probleme nur schwer nüchtern diskutieren lässt.
Das könnten zum Beispiel die Lernkurve oder die Komplexität beim Packaging sein.
Die Aussage „Jedes System kann C-Bibliotheken aufrufen“ stimmt heute nicht mehr.
Auch Rust und Zig erfüllen diese Anforderung.
Allerdings neigt Rusts Standardbibliothek bei OOM oft eher zu Panics als zu Recovery, und die Dokumentation dazu ist unzureichend.
extern "C"bzw.exportverwendet wird.Andernfalls ist die ABI nicht definiert und kann sogar instabiler als C++ sein.
Gerade bei Linux-Distributionen, die Rust-Crates ausliefern, kann dieses Problem noch größer werden.