Solod – 一种可以翻译成 C 的 Go 子集
Solod – A subset of Go that translates to C

原始链接: https://github.com/solod-dev/solod

## Solod (So): Go 到 C 转换器 Solod (So) 是一种新工具,可将 Go 代码的一个子集直接转换为可读的 C11 代码,提供一种使用 Go 语法和类型安全的系统编程方法。它具有零运行时开销——没有垃圾回收或隐藏分配——默认使用栈分配,并可选择使用堆。 So 能够实现与 C 代码的无缝原生互操作,无需 CGO,允许在 So 和 C 函数之间进行调用。它支持 Go 的核心特性,如结构体、方法、接口和切片,同时为了简单起见,省略了通道、协程、闭包和泛型。 你可以使用标准的 Go 工具(linting、测试、LSP)来处理 So 项目。过程包括使用 So 包编写 Go 代码,然后使用 `so` 命令将其转换为 C。编译可以使用 GCC、Clang 或 Zig 完成,目前支持 Linux、macOS 和 Windows(仅核心语言)。 虽然仍在开发中,So 旨在为系统编程提供一种快速高效的替代方案,利用 Go 的熟悉性,同时提供 C 的性能和控制。

## Solod:一个编译为C的Go子集 Solod是一个新项目,旨在提供Go编程语言的一个子集,可以直接翻译成C代码(github.com/solod-dev)。目标并非完全兼容Go,而是找到一个平衡点,提供Go的语法和空间内存安全,同时避免像goroutine、channel、closure和泛型等特性。 讨论的中心在于权衡。一些人质疑其价值主张,认为如果目标是C互操作性,直接使用C更简单。另一些人指出,Solod偏离标准Go语义——特别是块作用域的`defer`,而不是Go的函数作用域版本——引发了对测试和可靠性的担忧。 然而,一些开发者看到了潜力,尤其是在Go的并发特性不必要,并且需要直接C集成的情况下。有人将其与Vlang和tinyGo等其他项目进行比较,并建议将其与Neco等协程库集成。最终,该项目似乎是由利用Go语法在Go运行时不适用的环境中的愿望驱动的。
相关文章

原文

Solod (So) is a strict subset of Go that translates to regular C — with zero runtime, manual memory management, and source-level interop.

Highlights:

  • Go in, C out. You write regular Go code and get readable C11 as output.
  • Zero runtime. No garbage collection, no reference counting, no hidden allocations.
  • Everything is stack-allocated by default. Heap is opt-in through the standard library.
  • Native C interop. Call C from So and So from C — no CGO, no overhead.
  • Go tooling works out of the box — syntax highlighting, LSP, linting and "go test".

So supports structs, methods, interfaces, slices, multiple returns, and defer. To keep things simple, there are no channels, goroutines, closures, or generics.

So is for systems programming in C, but with Go's syntax, type safety, and tooling.

ExampleInstallation and usageLanguage tourStdlibPlaygroundSo by exampleTestingBenchmarksCompatibilityDesign principlesFAQRoadmapContributing

This Go code in a file main.go:

package main

type Person struct {
    Name string
    Age  int
    Nums [3]int
}

func (p *Person) Sleep() int {
    p.Age += 1
    return p.Age
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    p.Sleep()
    println(p.Name, "is now", p.Age, "years old.")

    p.Nums[0] = 42
    println("1st lucky number is", p.Nums[0])
}

Translates to a header file main.h:

#pragma once
#include "so/builtin/builtin.h"

typedef struct main_Person {
    so_String Name;
    so_int Age;
    so_int Nums[3];
} main_Person;

so_int main_Person_Sleep(void* self);

Plus an implementation file main.c:

#include "main.h"

so_int main_Person_Sleep(void* self) {
    main_Person* p = (main_Person*)self;
    p->Age += 1;
    return p->Age;
}

int main(void) {
    main_Person p = (main_Person){.Name = so_str("Alice"), .Age = 30};
    main_Person_Sleep(&p);
    so_println("%.*s %s %" PRId64 " %s", p.Name.len, p.Name.ptr, "is now", p.Age, "years old.");
    p.Nums[0] = 42;
    so_println("%s %" PRId64, "1st lucky number is", p.Nums[0]);
}

Check out more examples in So by example and learn about the supported language features in the language tour.

Install the So command line tool:

go install solod.dev/cmd/so@latest

Create a new Go project and add the Solod dependency to use the So standard library:

go mod init example
go get solod.dev@latest

Write regular Go code, but use So packages instead of the standard Go packages:

package main

import "solod.dev/so/math"

func main() {
    ans := math.Sqrt(1764)
    println("Hello, world! The answer is", int(ans))
}

Transpile to C:

so translate -o generated .

The translated C code will be saved in the generated directory.

You can also transpile to C and compile the code to a binary in one step. This uses the C compiler set by the CC environment variable:

Or you can transpile, compile, and run without saving the binary:

All commands work with Go modules, not individual files (so run ., not so run main.go).

Keep in mind that So is new, so it's still a bit rough around the edges.

To learn about So's features and limitations, check out the brief overview of the language.

So provides a growing set of high-level packages similar to Go's stdlib, as well as low-level packages that wrap the libc API.

Try So online without installing anything. You can run the code or view the translated C output.

If you like learning by doing, try a hands-on introduction to So with annotated example programs.

So doesn't have its own testing framework. Since So code is valid Go code, you can just use go test like you normally would. Plus, your tests can use all Go features because they're never transpiled.

The transpilation logic is covered by the So compiler's own tests.

So truly shines when it comes to C interop, but it's also quite fast on regular Go code — typically on par with or faster than Go.

So generates C11 code that relies on several GCC/Clang extensions:

  • Binary literals (0b1010) in generated code.
  • Statement expressions (({...})) in macros.
  • __attribute__((constructor)) for package-level initialization.
  • __auto_type for local type inference in generated code.
  • __typeof__ for type inference in generic macros.
  • alloca for make() and other dynamic stack allocations.

You can use GCC, Clang, or zig cc to compile the transpiled C code. MSVC is not supported.

Supported operating systems: Linux, macOS, and Windows (core language only).

So is highly opinionated. Simplicity is key. Heap allocations are explicit. Strictly Go syntax.

Frequently asked questions

I have heard these several times, so it's worth answering.

✅ Transpiler with basic Go features.

✅ Low-level stdlib (libc wrappers). Done for now; I will add more if needed.

⏳ Core stdlib packages: fmt, io, strings, time, ...

⏳ Maps.

⬜ Hardened transpiler.

⬜ Real-world examples.

⬜ More stdlib packages: crypto, http, json, ...

⬜ Full Windows support.

Bug fixes are welcome. For anything other than bug fixes, please open an issue first to discuss your proposed changes. To prevent feature bloat, it's important to discuss any new features before adding them.

AI-assisted submissions are fine on one condition: you, the human, have read all the code and fully understand what it does. Code reviewed only by another AI will not suffice.

Make sure to add or update tests as needed.

Go stdlib code by the Go Authors.

Transpiler and So stdlib code by Anton Zhiyanov.

Released under the BSD 3-Clause License.

联系我们 contact @ memedata.com