Live data from Hacker News

C2Rust: translate C into Rust code

c2rust.com

51–60 of 79 posts

Re: C2Rust: translate C into Rust code

#51

Earlier quoted context omitted.

Even though it's translating to unsafe Rust, it does still have some value. In particular, C libraries can be converted into Rust libraries that can be managed via Cargo, avoiding the need to deal with C tooling.

As a user of a C library in Cargo, you don't need to deal with C tooling, just have it installed.

That means anyone that wants to use a Rust crate that depends on a C library has to somehow install the C library. It's possible that's easy through a package manager, or maybe it's not, and you have to build the C library, and now you have to deal with C tooling.

Re: C2Rust: translate C into Rust code

#52

Earlier quoted context omitted.

If we had a standard for safe C that the linux kernel could feasibly meet, then it could be a condition of future changes that it continue to be safe. As you say, it's pretty hypothetical on both fronts--we're not gonna be able to prove that about a C project like the kernel, and they're not gonna rewrite in Rust any time soon.

As I see it the main benefits of C over using other languages like Rust, are generally the ease of getting access to raw memory, sharing pointers, and direct access to hardware. Rust is actually good at all of that too, but is just as unsafe. The point I’m making is that the mythical “safe C”, would have to remove many of the benefits of why people enjoy C, so why not just use Rust at that point? One variation I’ve s…

Makes sense--I agree.

Re: C2Rust: translate C into Rust code

#53
post #24

This is compiling C into very unsafe Rust as a target language: pub unsafe extern "C" fn insertion_sort(n: libc::c_int, p: *mut libc::c_int) -> () { let mut i: libc::c_int = 1i32; while i 0i32 && *p.offset((j - 1i32) as isize) > tmp { *p.offset(j as isize) = *p.offset((j - 1i32) as isize); j -= 1 } *p.offset(j as isize) = tmp; i += 1 }; } The output is unmaintainable, like the output from a compiler. This isn't trans…

I know and agree that unsafe Rust is problematic, but that criticism of this is missing the forest for the trees. The original code is just as unsafe.

Refactoring from unsafe Rust into safe Rust manually is likely to be easier than directly from C into Rust: one is only trying to deal with one small delta (like changing length/pointer arguments into a slice) rather than also having to deal with syntax changes and tooling issues.

As others have said, it is essentially impossible to automatically translate to safe Rust without non-trivial annotation effort, since C the language and C in practice is very different to how Rust guarantees safety. It seems to me that that "annotation" effort is probably better spent going unsafe to safe Rust (where, subjectively, the language is nicer to use, like better enums and less error prone control flow) rather than annotating the original C.

Re: C2Rust: translate C into Rust code

#54
post #21

I think the next step would be to have a tool that can convert C into safe Rust with a combination of static analysis and framework/program-specific user-written rules to translate specific C framework constructs into Rust equivalents. An eventual goal could be for instance to automatically translate the Linux kernel with the aid of a lot of custom rules to handle its constructs.

I've tried to do that with my translator: https://gitlab.com/citrus-rs/citrus#readme

Refactoring C to Rust code is hard. It's not enough to derive bits of information function by function. Often you need to re-architect the whole approach, which is a Sufficiently Smart Compiler problem. Until I've tried it I did not fully realize just how much C uses pointers. Pointer soup is everywhere (and hardly any explicit lengths anywhere).

In C's type system the concept of ownership doesn't exist. From that angle it's "dynamically typed". Converting "any pointer can have any ownership, it's implicit from usage" to Rust's "all ownership is statically known" is as hard as converting JavaScript's use of types to a statically-typed language.

Re: C2Rust: translate C into Rust code

#55

Earlier quoted context omitted.

As a user of a C library in Cargo, you don't need to deal with C tooling, just have it installed.

That means anyone that wants to use a Rust crate that depends on a C library has to somehow install the C library. It's possible that's easy through a package manager, or maybe it's not, and you have to build the C library, and now you have to deal with C tooling.

Some packages give you the option to check for a preinstalled package, and build it if it’s not there.

It works pretty cleanly, but it is true that one toolchain is easier than two.

Re: C2Rust: translate C into Rust code

#56
If you try making p a local array of length 10, ordinary Rust subscripting comes out. So the translator knows what to do with arrays; it just makes very C-ish assumptions about them. It just needs to know when a pointer is really an array to treat it as an array.

This has potential. If you had some way to annotate or advise the translator, it could do a much better job, and turn out safe, usable Rust.

Some of that can be done automatically by looking at calls to functions. If it's always an array going in, the formal parameter can become an array. Any C that doesn't have explicit pointer arithmetic should be translated into Rust that doesn't have explicit pointer arithmetic.

Re: C2Rust: translate C into Rust code

#57

Earlier quoted context omitted.

As a user of a C library in Cargo, you don't need to deal with C tooling, just have it installed.

That means anyone that wants to use a Rust crate that depends on a C library has to somehow install the C library. It's possible that's easy through a package manager, or maybe it's not, and you have to build the C library, and now you have to deal with C tooling.

That only applies to shared libraries. If the crate builds the library and links it statically, you don't see the tooling.

Re: C2Rust: translate C into Rust code

#58

Earlier quoted context omitted.

That means anyone that wants to use a Rust crate that depends on a C library has to somehow install the C library. It's possible that's easy through a package manager, or maybe it's not, and you have to build the C library, and now you have to deal with C tooling.

That only applies to shared libraries. If the crate builds the library and links it statically, you don't see the tooling.

Don't you still need C tooling setup for the crate to build the C library?

Especially on Windows, this can be a pain.

Re: C2Rust: translate C into Rust code

#59
post #29

Earlier quoted context omitted.

The compilation target could be a Rust slab [0], much like Emscripten uses Typed Arrays [1]. In doing so, it would retain much of the safety properties of Rust, but it pushes the problem into maintaining "the heap" for the C code. [0] https://github.com/carllerche/slab [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Type...

That would be significantly less useful if the intent is to move the code from C to Rust.

How so?

It allows unsafe C to be incorporated into safe Rust while maintaining the same level of safety.

A similar less ergonomic solution would be to load C via WASM modules.

I'd take slab or wasm over whole lib translation into unsafe Rust.

Re: C2Rust: translate C into Rust code

#60
post #21

I think the next step would be to have a tool that can convert C into safe Rust with a combination of static analysis and framework/program-specific user-written rules to translate specific C framework constructs into Rust equivalents. An eventual goal could be for instance to automatically translate the Linux kernel with the aid of a lot of custom rules to handle its constructs.

There's a real sense in which, if this were true, we might not need Rust. If we could mechanically translate the Linux kernel to safe Rust, we could prove the Linux kernel safe. If we could prove the Linux kernel safe, that would be a strong argument against a need to translate it to Rust. Note that this point is independent of the question of whether rewriting the Linux kernel in Rust is actually good/feasible idea.…

That assumes that such a translation is either a binary success/failure, runs at once, and runs for the entire kernel.

More likely, such a tool will be used file-by-file and module-by-module, and when it fails, it will either report obvious mistakes (that will then be fixed in the C source, in the same way that e.g. people doing Python 2 to 3 conversions end up fixing bugs in their Python 2 code to prepare it for reliable conversion) or report more complex design mistakes that warrant rethinking an approach from scratch and starting the new implementation in Rust.

If that's what happens, then we would not be proving the Linux kernel safe, and we would have a strong argument for having done the translation.

Post reply on HN