11 ms·
C2rust: Transpile C to Rust
- foxfluff 5y agoIt seems to "optimize out" volatile reads if the result is not used.
- TickleSteve 5y agoIf true, that would be a bug. You dont want to remove register reads from devices for example if the device requires it.
- tialaramex 5y agoIt looks to me like they're turned into the appropriate Rust intrinsic. Do you have an example where the read vanishes? Notice that it's very easy for C programmers to write code they think is performing a volatile read, but isn't, whereas obviously the intrinsics reduce the scope for this error in the Rust (it is also, though that's not relevant here, easy to write C code that depends on imaginary semantics of volatile access and so the code doesn't actually always work, or it works but not for the reason the programmer expected)
- foxfluff 5y agoIf you believe there is no volatile read in this code, I'd like to understand why. void func(volatile unsigned *a) { *a; }
- tialaramex 5y agoNope, I agree that's a volatile read, and indeed the web page doesn't emit the appropriate intrinsic, nor indeed do small modifications that result in a read of the pointer, cause the intrinsic to be used as I'd anticipated. Definitely something to be wary of. I assure you the c2rust source code does know about volatile access and Rust's intrinsics (I was looking at that code for other reasons), so if you work with this stuff I'd encourage talking to the people who wrote it to find out what the situation is.
- detaro 5y agoHave their been any large projects that used this as a starting point for a port? I would be curious how it works out in practice.
- billconan 5y agoBut what about borrow checking? Will the transpiled code be runnable.
- deleted 5y ago[deleted]
- qw3rty01 5y agoit doesn't convert pointers to references, it just uses pointers, so the borrow checker isn't invoked.
- TheMagicHorsey 5y agoFor the non-Rust programmers here, does that mean you don't get Rust's memory safety with this transpiler?
- deleted 5y ago[deleted]
- qw3rty01 5y agoCorrect, although it looks like converting some parts to safe code may be a future goal
- steveklabnik 5y agoWhat they've stated previously is that they plan to go with the approach of "compile C to unsafe Rust" and "compile unsafe Rust to safe Rust" as two separate things that could be chained together. I don't remember if it's meant to be literally another tool or just the general approach, but seems very interesting and sensible to me!
- acomjean 5y agoWe used to call fortran transpired into ada: adatran. Adatran was terrible. Hard to impossible to edit if something needed fixing. Used none of the features that made Ada a decent language. The very limited code they did this to did work however. This was a huge project and included C and ada code. What do we call C code transpiled to Rust. Crust?
- pcwalton 5y ago> What do we call C code transpiled to Rust. Crust? Fun fact: in ancient Rust, what we now call extern "C" functions were called "crust" functions, pronounced like the word.
- hunterb123 5y agoRust devs are commonly called Rustaceans, so users of this transpiler could circle back to the term Crustaceans.
- deltaonefour 5y agoThink of the transpiled code as a compiled binary. Have your build system be able to recognize both languages. So developers work in C and Rust, but they don't actually work in transpiled rust. I guess this is similar to using the FFI.
- drran 5y agoYep. https://github.com/NishanthSpShetty/crust https://github.com/NishanthSpShetty/crust CRUST C/C++ to Rust Transpiler
- mjcohen 5y agoMany years ago, I used the f2c fortran to c translator. It worked, but produced godawful code. I removed about 75% of the c to get usable code.
- masklinn 5y agoYou’re misunderstanding the c2rust project though. Just like Walter above is. The goal of c2rust is not “regularly compile C to Rust and keep compiling that garbage”. The goal of c2rust is “migrate a C codebase to Rust”. That is the tagline of the Git repository, as well as the title of the RustConf 2018 presentation linked in TFA. The idea is that you convert the entire thing to working (but unsafe and C-equivalent) Rust, then have your entire build pipeline and tooling ready to chip at it and perform the conversion to safe rust, as an alternative to performing the conversion piecemeal and having a C/Rust boundary which you have to keep moving about, and duplicated definitions for the interop.
- WalterBright 5y agoWe kinda gave up on translating C into D, as many C constructs were unduly awkward to represent in D. What's working much better is to incorporate a C compiler directly into the D compiler. No need to translate, and the C semantics can be adhered to exactly. (The D compiler is extended to understand the C semantics coming from the C code, although that isn't part of the D specification.)
- WalterBright 5y agoSome examples of awkwardness: 1. C tag name space 2. enum values are placed into the enclosing scope 3. structs defined within a struct definition don't go into that definition's scope 4. `if (a = b)` is not allowed in D 5. unprototyped C function declarations 6. C bit fields 7. C struct declarations without a definition 8. oddities of _Alignas and _Alignof behavior 9. _Generic 10. all the weird C compiler extensions 11. etc. All these things wind up making translation about 95% feasible, and the rest is a mess.
- jeffparsons 5y agoWhile your approach to this in D is super-cool, and I love seeing more projects embracing it (e.g. `zig cc` for cross-compiling C code), I think it solves a different problem to what they're tackling here. FTA: > We are developing several tools that help transform the initial Rust sources into idiomatic Rust. It sounds like this translator they've built may be meant primarily as the first part of a pipeline of tools to help you eventually translate existing C code into idiomatic Rust, rather than just letting you compile C code using the Rust compiler. The only use case I can imagine personally having for this tool _on its own_ would be in avoiding the hell of trying to target musl with a project that mixes Rust and C.
- WalterBright 5y agoThe trouble with translating existing C code, for example, a .h file, is the .h file vendor changes it. Then you've got to figure out what changed, and fold in the differences to the translated file. It sounds easy enough in theory, but in practice, it's a nightmare. For example, you have no clue if the enum values changed, or the api's acquired an extra argument. Being C, the linker won't give you a clue, either. This problem simply vanishes when your XLang compiler can actually compile C files.
- ronlobo 5y agoPromising! Has anybody incorporated an AI into c2rust to do the heavy lifting and learning from the compiler errors to self fix the transpiled code?
- speed_spread 5y agoI doubt an AI could be trained to do that. Anything that cannot be transpiled mechanically probably requires a human decision which will involve analysis and tradeoffs between objectives that the AI could not know about.
- gnulinux 5y agoWith enough work, anything a human does can be automated. Unless you believe human brain does something non-computable (like e.g. Godel), which makes you a dualist which comes with its own philosophical baggage (how do different types of ontologies interact?).
- yjftsjthsd-h 5y agoOne need not delve into philosophy to observe that, in practice, humans can do many things that we have yet to make machines do successfully. I admit that this is like solving the halting problem by saying "yes" (https://xkcd.com/1266/ https://xkcd.com/1266/), for better and worse. (But seriously, I think it's fair to say "as of 2022, no, AI can't do that")
- speed_spread 5y agoSure, the machine could "make a call" and pick a way of doing things, but that machine wouldn't be the one supporting the resulting code for years afterward. Past a certain point, some technical decisions become value judgements because of their impact on humans.
- rgovostes 5y agoBack in the day there was also Corrode: https://github.com/jameysharp/corrode https://github.com/jameysharp/corrode Discussed here: https://news.ycombinator.com/item?id=12056230 https://news.ycombinator.com/item?id=12056230
- techdragon 5y agoThis looks more useful than some other C to Rust tools, as this will work on code directly instead of the finally linked product, allowing you to use it to port larger library collections or SDKs ahead of time for use in a subsequent Rust project. This can also be used on any old random snippet of valid C, (known limitations aside) This will be fantastic for helping encourage Rust on microcontrollers. The microcontroller world is very C heavy, so libraries for daughter board and other chips, and other example code, is often only published in C, despite the growing ecosystem of microcontroller chips and boards that have good support for Rust, you end up constantly pushed towards C due to the ecosystem basically only using C. Having a good tool to take that C code and give at least a mechanical, non-idiomatic Rust port is just fantastic and I'm looking forward to giving this a shot with a particular add on board SDK that I wanted to use on a Rust supported microcontroller.
- mastax 5y agoNot mentioned on this page is the associated refactoring tool (https://c2rust.com/manual/c2rust-refactor/index.html https://c2rust.com/manual/c2rust-refactor/index.html) which IME is too complicated to learn in 15 minutes, but would likely be a very useful investment when translating a large code base.
- the-alt-one 5y agoWhy is this a transpiler and not a compiler?
- detaro 5y agoa transpiler is a compiler.
- the-alt-one 5y agoSo why is it a transpiler and not only a compiler?
- detaro 5y agoBecause it compiles to a programming language of same or higher level of abstraction.
- the-alt-one 5y agoAre the techniques used different in such a case? Shouldn't it just be the same? Basically F(C) = R such that eval_C(C) = eval_R(R) where = means something like "discernible effects". Wouldn't an optimization pass be a transpiler then?
- detaro 5y agoA bunch of things a compiler "going downwards" needs to do don't apply, e.g. you don't need to worry about registers and things like that. And there's potentially more complex concepts to map to instead of just breaking source-language concepts down. Haven't seen that terminology applied to individual passes.
- the-alt-one 5y agoMost compilers don't have to worry about registers nowadays, since they compile to LLVM or C.
- kitd 5y agoHmm. Transpile C to "Rust" edit: I see it is part of a broader toolchain, which makes a bit more sense
- JoelJacobson 5y agohttps://github.com/immunant/c2rust https://github.com/immunant/c2rust: > We rely on Emscripten's Relooper algorithm to translate arbitrary C control flows. Article on why Relooper isn't good enough and the superior Stackifier algorithm, which they probably should be using instead: https://medium.com/leaningtech/solving-the-structured-control-flow-problem-once-and-for-all-5123117b1ee2 https://medium.com/leaningtech/solving-the-structured-contro...
- andrew_mason1 5y agoShame it's not called `crust`. Very cool though!
- jokoon 5y agoI'm curious how it manages to work with the borrow checker.
- Lorkki 5y agoThe end result is unsafe Rust that uses raw pointers. This kind of tool can be used e.g. as a starting point for rewriting codebase piece by piece, retaining the original functionality as a baseline.