Live data from Hacker News

Why Is SQLite Coded In C

sqlite.org

301–310 of 411 posts

Re: Why Is SQLite Coded In C

#301

Earlier quoted context omitted.

Can’t compile with just a PDF file, though.

Yes, compilers will take some time to implement the new standards. C23 seems to have decent support from a few compilers, with GCC leading the pack: https://en.cppreference.com/w/c/compiler_support/23.html gcobol supports (or at least aims to support?) COBOL 2023: https://gcc.gnu.org/onlinedocs/gcc-15.1.0/gcobol/gcobol.html . Presumably there are other compilers working on support as well. Intel's Fortran compiler an…

Flang does already support warnings for features that have breaking changes in F’2023.

Re: Why Is SQLite Coded In C

#302
post #273

Earlier quoted context omitted.

This is a bit of a misunderstanding. Safe code is just code that cannot have Undefined Behavior. C and C++ have the concept of "soundness" just like Rust, just no way to statically guard against it.

Modern compilers like clang and GCC both have static analysis for some of this. Check out the undefined behavior sanitizer.

As the other person pointed out, these are two different things. Sanitizers add runtime checks (with zero consideration for performance - don’t use these in productions). Static analysis runs at compile time, and while both GCC and Clang are doing amazing jobs of it, it’s still very easy to run into trouble. The mostly catch the low-hanging fruit.

The technical reason is that Rust-the-language gives the compiler much more information to work with, and it doesn’t look like it is possible to add this information to the C or C++ languages.

Re: Why Is SQLite Coded In C

#303
post #205
post #181

Earlier quoted context omitted.

What the best strategy is depends on your use case. The use case that SQLite has chosen to optimize for is critical embedded software. As described in https://www.sqlite.org/qmplan.html , the standard that they base their efforts on is a certification for use in aircraft. If mission critical software on a plane is allowed to crash, this can render the controls inoperable. Which is likely to lead to a very literal cra…

outside political definitions, I'm not sure "crash and restart with a supervisor" and "don't crash" are meaningfully different? they're both error-handling tactics, likely perfectly translatable to each other, and Erlang stands as an existence proof that crashing is a reasonable strategy in extremely reliable software. I fully recognize that political definitions drive purchases, so it's meaningful to a project eithe…

If the cause of the crash is in any way related to the persisted data, there's a good chance you're now stuck in a crashloop.

If it can avoid crashing, other functionality may continue to work fine.

Re: Why Is SQLite Coded In C

#304
post #71
post #13

Earlier quoted context omitted.

Turso: https://algora.io/challenges/turso "Turso is rewriting SQLite in Rust ; Find a bug to win $1,000" ------ - Dec 10, 2024 : "Introducing Limbo: A complete rewrite of SQLite in Rust" https://turso.tech/blog/introducing-limbo-a-complete-rewrite... - Jan 21, 2025 - "We will rewrite SQLite. And we are going all-in" https://turso.tech/blog/we-will-rewrite-sqlite-and-we-are-go... - Project: https://github.com/tursodat…

sqlite3 has one (apparently this is called "the amalgamation") c source file that is ~265 kloc (!) long with external dependencies on zlib, readline and ncurses. built binaries are libsqlite3.so at 4.8M and sqlite3 at 6.1M. turso has 341 rust source files spread across tens of directories and 514 (!) external dependencies that produce (in release mode) 16 libraries and 7 binaries with tursodb at 48M and libturso_sqli…

I don't think the SQLite authors actually edit the single giant source file directly. Their source control repository has the code split up into many separate files, which are combined into "the amalgamation" by a build script: https://github.com/sqlite/sqlite/tree/master/src

Re: Why Is SQLite Coded In C

#305
post #205
post #181

Earlier quoted context omitted.

What the best strategy is depends on your use case. The use case that SQLite has chosen to optimize for is critical embedded software. As described in https://www.sqlite.org/qmplan.html , the standard that they base their efforts on is a certification for use in aircraft. If mission critical software on a plane is allowed to crash, this can render the controls inoperable. Which is likely to lead to a very literal cra…

outside political definitions, I'm not sure "crash and restart with a supervisor" and "don't crash" are meaningfully different? they're both error-handling tactics, likely perfectly translatable to each other, and Erlang stands as an existence proof that crashing is a reasonable strategy in extremely reliable software. I fully recognize that political definitions drive purchases, so it's meaningful to a project eithe…

Yes, Erlang demonstrates that "crash and restart with a supervisor" is a potentially viable strategy to reliability.

But the choice is not just political. There are very meaningful technical differences for code that potentially winds up embedded in other software, and could be inside of literal embedded software.

The first is memory. It takes memory to run whatever is responsible for detecting the crash, relaunching, and starting up a supervisor. This memory is not free. Which is one of the reasons why Erlang requires at a minimum 10 MB or so of memory. By contrast the overhead of SQLite is something like half a MB. This difference is very significant for people putting software into medical devices, automotive controllers, and so on. All of which are places where SQLite is found, but Erlang isn't.

The second is concurrency. Erlang's concurrency model leaks - you can't embed it in software without having to find a way to fit Erlang concurrency in. This isn't a problem if Erlang already is in your software stack. But that's an architectural constraint that would be a problem in many of the contexts that SQLite is actually used in.

Remember, SQLite is not optimized for your use case. It is optimized for embedded software that needs to try to keep running when things go wrong. It just happens to be so good that it is useful for you.

Re: Why Is SQLite Coded In C

#306

Earlier quoted context omitted.

there is already an sqlite port in Go :) https://gitlab.com/cznic/sqlite

That's not a port. That's an extremely impressive machine translation of C to Go. The output is a non-portable half-a-million LoC Go file for each platform.

also unmaintainable and full of unsafe

Re: Why Is SQLite Coded In C

#307

> Safe languages insert additional machine branches to do things like verify that array accesses are in-bounds. In correct code, those branches are never taken. That means that the machine code cannot be 100% branch tested, which is an important component of SQLite's quality strategy. Huh it's not everyday that I hear a genuinely new argument. Thanks for sharing.

It's new because it makes no sense. There already is an implicit "branch" on every array access in C, it's called an access violation. Do they test for a segfault on every single array access in the code base? No? Then they don't really have 100% branch coverage, do they?

Take a look at their description of how SQLite is tested: https://www.sqlite.org/testing.html

I think a lot of projects that claim to have 100% coverage are overselling their testing, but SQLite is in another category of thoroughness entirely.

Re: Why Is SQLite Coded In C

#308

Earlier quoted context omitted.

> But (if I understand correctly) these are checks implicitly added by the compiler. This is a dubious statement. In Rust, the array indexing operator arr[i] is syntactic sugar for calling the function arr.index(i), and the implementation of this function on the standard library's array types is documented to perform a bounds-check assertion and access the element. So the checks aren't really implicitly added -- you…

Another commenter in this thread used the phrase "complex abomination" which seems more and more apt the more I learn about Rust.

Nothing in this world is perfect, but this behavior is less of an abomination than whatever a junior dev on a timeline might write to handle this condition.

Re: Why Is SQLite Coded In C

#309
post #93

It sounds like the core doesn't even allocate, and presumably the extended library allocates in limited places using safe patterns. So there wouldn't be much benefit from Rust anyway, I'd think. Had SQLite ever had a memory leak or use-after-delete bug on a production release? If so, that answers the question. But I've never heard of one. Also, does it use doubly linked lists or graphs at all? Those can, in a way, be…

> Had SQLite ever had a memory leak or use-after-delete bug on a production release? sure, it's an old library they had pretty much anything (not because they don't know what they are doing but because shit happens) lets check CVEs of the last few years: - CVE-2025-29088 type confusion - CVE-2025-29087 out of bounds write - CVE-2025-7458 integer overflow, possible in optimized rust but test builds check for it - CVE-…

Wow that's a great analysis!

Yeah I essentially agree. I'm sure there are still plenty of good cases for C, depending on project size, experience of the engineers, integration with existing libraries, target platform, etc. But it definitely seems like Rust would be the better option in scenarios where there's not some a priori thing that strongly skews toward or forces C.

Re: Why Is SQLite Coded In C

#310
post #102

Earlier quoted context omitted.

But does it matter if that control flow is unreachable? If the check never fails, it is logically equivalent to not having the check. If the code isn't "correct" and the panic is reached, then the equivalent c code would have undefined behavior, which can be much worse than a panic.

In the first case, if it is actually unreachable, I would never want that code ending up in my binary at all. It must be optimised out. Your second case implies that it is reachable.

In the first case, it often is optimized out. But the optimizer isn't perfect, and can't detect every case where it is unreachable.

If you have the second case, I would much rather have a panic than undefined behavior. As mentioned in another comment, in c indexing an array is semantically equivalent to:

    if (i 
In fact a c compiler could put in a check and abort if it is out of bounds, like rust does and still be in spec. But the undefined behavior could also cause memory corruption, or cause some other subtle bug.
Post reply on HN