<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/on-transpilers-k5pwwd8su" -->

---
title: On Transpilers | daily.dev
description: An experiment comparing three tools that transpile C source code into Go, Rust, and Zig, using a small self-written BASIC interpreter as the test case. The Go...
canonical: https://daily.dev/posts/on-transpilers-k5pwwd8su
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: On Transpilers | daily.dev
og:description: An experiment comparing three tools that transpile C source code into Go, Rust, and Zig, using a small self-written BASIC interpreter as the test case. The Go...
og:url: https://daily.dev/posts/on-transpilers-k5pwwd8su
og:image: https://api.daily.dev/og/posts/K5pwWD8su.png
og:image:alt: On Transpilers
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# On Transpilers

**[zserge's blog](https://daily.dev/sources/zserge)** · 9 min read · 0 upvotes · 0 comments

## Summary

An experiment comparing three tools that transpile C source code into Go, Rust, and Zig, using a small self-written BASIC interpreter as the test case. The Go tool ccgo (used to port SQLite to pure Go) produces verbose, unsafe-pointer-heavy code and crashed on an unimplemented libc function until printf was substituted for puts. Rust's c2rust was the hardest to install (needs LLVM) but produced the shortest, most reliable output with no manual fixes. Zig's built-in translate-c produced the most readable, structurally faithful output but failed on memmove until a hand-written replacement was substituted. The author concludes there's no outright winner among these 'better C' transpilers, but each offers a path to gradually migrate legacy C codebases to safer languages.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://zserge.com/posts/transpilers>

## Questions this post answers

### What C-to-Go transpiler was used to convert SQLite to pure Go without cgo?

The ccgo transpiler, available at gitlab.com/cznic/cc, was used to convert SQLite into pure Go with no cgo dependency, later published as modernc.org/sqlite. It relies on a custom C lexer, parser, and multi-phase AST walker, and depends on the modernc.org/libc runtime library for standard library features in the generated Go code.

_Track how C-to-Go migration tooling like ccgo evolves by following language and toolchain news on daily.dev._

### Does Zig's translate-c support memmove when converting C code to Zig?

No, memmove is not part of the Zig C runtime, so C code calling memmove fails when translated with zig translate-c. The workaround is replacing memmove with a hand-written equivalent function before transpiling; after that substitution, the generated Zig code compiles and runs correctly, matching the size and behavior of the original C binary.

_Developers weighing Zig's C interop maturity can follow toolchain gotchas like this one on daily.dev._

### How does c2rust compare to ccgo and zig translate-c in ease of use and output reliability?

c2rust was the hardest to install, requiring LLVM and other dependencies plus a CMake-based build setup rather than single-file transpilation, unlike ccgo (a single go install) or Zig's built-in translate-c. Despite the friction, c2rust produced the shortest generated code and ran correctly without any manual fixes, making it the most reliable of the three in this comparison.

_Compare tradeoffs between C migration tools like c2rust, ccgo, and translate-c on daily.dev before picking one._

## Similar posts on daily.dev

- [Thoughts on Go vs. Rust vs. Zig](https://daily.dev/posts/thoughts-on-go-vs-rust-vs-zig-knnqurolm) · Hacker News · 4 upvotes · 2 comments
- [How Our Rust-to-Zig Rewrite is Going](https://daily.dev/posts/how-our-rust-to-zig-rewrite-is-going-kvdc7iim2) · Lobsters · 5 upvotes · 1 comments
- [Zig creator seeks 'uncompromising perfection' before blessing 1.0](https://daily.dev/posts/zig-creator-seeks-uncompromising-perfection-before-blessing-1-0-xjndfdjvj) · DEVCLASS · 28 upvotes · 14 comments

---

Tags: [#golang](https://daily.dev/tags/golang), [#rust](https://daily.dev/tags/rust), [#c](https://daily.dev/tags/c), [#zig](https://daily.dev/tags/zig)

[View this post on daily.dev](https://daily.dev/posts/on-transpilers-k5pwwd8su)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"On Transpilers","url":"https://daily.dev/posts/on-transpilers-k5pwwd8su","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/on-transpilers-k5pwwd8su"},"datePublished":"2026-08-23T10:20:22.963Z","dateModified":"2026-08-23T10:21:54.541Z","description":"An experiment comparing three tools that transpile C source code into Go, Rust, and Zig, using a small self-written BASIC interpreter as the test case. The Go...","image":"https://media.daily.dev/image/upload/s--2-1xRawN--/f_auto/v1722860399/public/Placeholder%2011","thumbnailUrl":"https://media.daily.dev/image/upload/s--2-1xRawN--/f_auto/v1722860399/public/Placeholder%2011","isAccessibleForFree":true,"articleSection":"zserge's blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"zserge's blog","logo":"https://media.daily.dev/image/upload/s--KQnFBOIT--/f_auto,q_auto/v1787480407/logos/zserge","url":"https://daily.dev/sources/zserge"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/on-transpilers-k5pwwd8su","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"golang,rust,c,zig","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"zserge's blog","item":"https://daily.dev/sources/zserge"},{"@type":"ListItem","position":3,"name":"On Transpilers"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/on-transpilers-k5pwwd8su#faq","mainEntity":[{"@type":"Question","name":"What C-to-Go transpiler was used to convert SQLite to pure Go without cgo?","acceptedAnswer":{"@type":"Answer","text":"The ccgo transpiler, available at gitlab.com/cznic/cc, was used to convert SQLite into pure Go with no cgo dependency, later published as modernc.org/sqlite. It relies on a custom C lexer, parser, and multi-phase AST walker, and depends on the modernc.org/libc runtime library for standard library features in the generated Go code. Track how C-to-Go migration tooling like ccgo evolves by following language and toolchain news on daily.dev."}},{"@type":"Question","name":"Does Zig's translate-c support memmove when converting C code to Zig?","acceptedAnswer":{"@type":"Answer","text":"No, memmove is not part of the Zig C runtime, so C code calling memmove fails when translated with zig translate-c. The workaround is replacing memmove with a hand-written equivalent function before transpiling; after that substitution, the generated Zig code compiles and runs correctly, matching the size and behavior of the original C binary. Developers weighing Zig's C interop maturity can follow toolchain gotchas like this one on daily.dev."}},{"@type":"Question","name":"How does c2rust compare to ccgo and zig translate-c in ease of use and output reliability?","acceptedAnswer":{"@type":"Answer","text":"c2rust was the hardest to install, requiring LLVM and other dependencies plus a CMake-based build setup rather than single-file transpilation, unlike ccgo (a single go install) or Zig's built-in translate-c. Despite the friction, c2rust produced the shortest generated code and ran correctly without any manual fixes, making it the most reliable of the three in this comparison. Compare tradeoffs between C migration tools like c2rust, ccgo, and translate-c on daily.dev before picking one."}}]}
```

