[HN Gopher] Rust to C compiler - 95.9% test pass rate, odd platf...
___________________________________________________________________
Rust to C compiler - 95.9% test pass rate, odd platforms
Author : todsacerdoti
Score : 241 points
Date : 2025-04-12 04:21 UTC (18 hours ago)
(HTM) web link (fractalfir.github.io)
(TXT) w3m dump (fractalfir.github.io)
| claudiojulio wrote:
| Very cool. C to Rust would be fantastic.
| ndndjdnd wrote:
| What benefit would you envision from this?
| trentearl wrote:
| There is DARPA program called TRACTOR to pursue this:
|
| https://www.darpa.mil/news/2024/memory-safety-
| vulnerabilitie...
| IshKebab wrote:
| 1. It means you don't need C code & a C compiler in your
| project any more, which simplifies infrastructure. E.g. cross
| compiling is easier without any C.
|
| 2. You can do LTO between Rust and the C->Rust code so in
| theory you could get a smaller & faster executable.
|
| 3. In most cases it is the first step to a gradual rewrite in
| idiomatic Rust.
| Aurornis wrote:
| > C to Rust would be fantastic.
|
| This would have to go into one big unsafe block for any
| nontrivial program. C doesn't convey all of the explicit things
| you need to know about the code to make it even compile in
| Rust.
| JonChesterfield wrote:
| If your translator is correct, the rust front end enforces
| the semantics of rust then C implements them. It's as safe as
| any other implementation.
|
| If that feels uncomfortable, consider that x64 machine code
| has no approximation to rust safety checks, and you trust
| rust binaries running on x64.
|
| "Correct" is doing some heavy lifting here but generally
| people seem willing to believe that their toolchain is bug
| free.
| pests wrote:
| They are discussing C to Rust, not the topic of the post.
| Rust would need to guess the semantics of the original C.
| CryZe wrote:
| I once implemented a WASM to Rust compiler that due to WASM's
| safety compiles to fully safe Rust. So I was able to compile
| C -> WASM -> Rust and ended up with fully safe code. Though
| of course, just like in WASM, the C code is still able to
| corrupt its own linear memory, just can't escape the
| "sandbox". Firefox has employed a similar strategy:
| https://hacks.mozilla.org/2020/02/securing-firefox-with-
| weba...
| sitkack wrote:
| I'd love to check that out. Did it unroll a wasm
| interpreter into wasm_op function calls?
| CryZe wrote:
| There's no interpreter, I just map each instruction to
| equivalent Rust code. Linear memory is accessed through a
| trait.
|
| The compiler is here: https://github.com/CryZe/wasm-to-
| rust
|
| I have an example of a GameBoy emulator compiled from
| AssemblyScript to WASM to Rust here:
| https://github.com/CryZe/wasmboy-
| rs/blob/master/src/wasm.rs
| sitkack wrote:
| That is super cool!
|
| Have you run into any limitations?
|
| Have you tried running in loop, wasm->rust->wasm->rust ?
|
| This is not-unlike unrolling an interpreter. There was a
| lua2c project that did something similar.
| fabrice_d wrote:
| See https://github.com/immunant/c2rust
| g-mork wrote:
| Mark Russinovich recently gave a talk at a UK Rust conference
| that mentioned Microsoft's internal attempts at large scale
| C->Rust translation,
| https://www.youtube.com/watch?v=1VgptLwP588
| pjmlp wrote:
| Note the AI part of the tooling.
| jeroenhd wrote:
| Tools like those exist. The problem with them is that they use
| unsafe blocks a lot, and the code usually isn't very idiomatic.
| Translating global variable state machines into more idiomatic
| Rust state machines based on things like named enums, for
| instance, would be very difficult.
|
| With the help of powerful enough AI we might be able to get a
| tool like this, but as AI still very much sucks at actually
| doing what it's supposed to do, I don't think we're quite ready
| yet. I imagine you'd also need enough memory to keep the entire
| C and Rust code base inside of your context window, which would
| quickly require very expensive hardware once your code grows
| beyond a certain threshold. If you don't, you end up like many
| code assisting LLMs, generating code independently that's
| incompatible with itself.
|
| Still, if you're looking to take a C project and extend it in
| Rust, or perhaps slowly rewrite it piece by piece,
| https://c2rust.com/ is ready for action.
| Krutonium wrote:
| But does it carry the Rusty guarantees?
| cryptonector wrote:
| Why wouldn't it?
| pornel wrote:
| It could fail if the generated C code triggered Undefined
| Behavior.
|
| For example, signed overflow is UB in C, but defined in Rust.
| Generated code can't simply use the + operator.
|
| C has type-based alias analysis that makes some type casts
| illegal. Rust handles alias analysis through borrowing, so
| it's more forgiving about type casts.
|
| Rust has an UnsafeCell wrapper type for hacks that break the
| safe memory model and would be UB otherwise. C doesn't have
| such thing, so only uses of UnsafeCell that are already
| allowed by C are safe.
| FractalFir wrote:
| I have workarounds for all "simple" cases of UB in C(this
| is partially what the talk is about). The test code is
| running with `-fsantize=undefined`, and triggers no UB
| checks.
|
| There are also escape hatches for strict aliasing in the C
| standard - mainly using memcpy for all memory operations.
| bregma wrote:
| Wait until you find out how unsafe software written in the
| machine language that Rust usually transpiles to is.
| adwn wrote:
| That's not the same, and not what pornel is talking
| about. The x86 _ADD_ instruction has a well-defined
| behavior on overflow, and _i32 + i32_ in Rust will
| usually be translated to an _ADD_ instruction, same as
| _int + int_ in C. But a C compiler is allowed to assume
| that a signed addition operation will never overflow (the
| dreaded _Undefined Behavior_ ), while a Rust compiler
| must not make that assumption. This means that _i32 +
| i32_ must not be translated to _int + int_.
|
| For example, a C compiler is allowed to optimize the
| expression _a+1 <a_ to _false_ (if _a_ is signed), but a
| Rust compiler isn 't allowed to do this.
| cryptonector wrote:
| > It could fail if the generated C code triggered Undefined
| Behavior.
|
| > For example, signed overflow is UB in C, but defined in
| Rust. Generated code can't simply use the + operator.
|
| Obviously, yes, but it could generate overflow checks.
| GolDDranks wrote:
| If the transpilation itself is bug-free, why not? For static
| guarantees, provided we transpile Rust code that already
| compiles on a normal Rust compiler, the guarantees are already
| checked and there, and the dynamic ones such as bounds checking
| can be implemented runtime in C with no problems.
| chii wrote:
| this assumes the rusty guarantees are transitive. There's no
| reason to believe it isn't, but it'd be nice to see some sort
| of proof, or at least an argument for it.
| josephg wrote:
| Should be. The rust borrow checker has no runtime
| component. It checks the code as-is before (or during)
| compilation.
|
| Arguably it's not the compiled binary that's "safe". It's
| the code.
| kreetx wrote:
| Borrow checker, and more generally any type checkers, are
| essentially terminating programs ran during compilation
| process, thus safety guarantees given by them are ensured
| _before_ the code is transformed into some target
| language.
| olivermuty wrote:
| Thats assuming lossless transpilation though
| carlmr wrote:
| That's a problem for almost every language, not just
| Rust. C++ also compiles to intermediate representations,
| and then to machine code. Errors happen on that path.
| Rust just get rid of a lot of errors that could have been
| in the original specification (the source code).
| kreetx wrote:
| If you mean 'no bugs in compiler' then yes. The safety of
| the target language doesn't matter: the output C is has
| an equivalent role to output machine code, those
| languages themselves are as unsafe as they can get, it's
| just that compilers output is a safer subsection of 'all
| programs which can be expressed in them'.
| fpoling wrote:
| Rust does not generate machine code itself. It uses LLVM to
| do that and there is no proof that the transformations done
| by that continue to keep the borrow checker guarantees. One
| just assumes with sufficient testing all bugs will be
| discovered.
|
| Then the machine code generated by LLVM is not run directly
| by modern CPUs and is translated into internal
| representation first. And the future CPUs will behave like
| JIT-compilers with even more complex transformations.
|
| The intermediate C code generated by this project just adds
| yet another transformation not fundamentally different from
| any of the above.
| db48x wrote:
| I'm not convinced that it's worth spending any time supporting
| most proprietary systems. Maybe not even Windows, but especially
| the really expensive ones.
| o11c wrote:
| You shouldn't spend your _own_ effort; you should make it clear
| that you 're open to users of such systems contributing.
|
| That's how GCC became so dominant - there were people already
| using all sorts of Unixen and they wanted a compiler, so they
| made it work.
| weinzierl wrote:
| That is absolutely true but exotic platforms are also fun to
| investigate and you can learn a lot. So I'd say you shouldn't
| spend your _own_ effort if you don 't want to but I am glad
| fractalfir did and I am looking forward to the his RustWeekNL
| presentation.
| eru wrote:
| Of course, accepting contributions comes with some effort,
| too.
| lmm wrote:
| > You shouldn't spend your own effort; you should make it
| clear that you're open to users of such systems contributing.
|
| In practice you can't really draw a line between those two
| things.
|
| I don't know the end result, but I remember a discussion of
| how implementing parts of Git in Rust would be a problem
| because NonStop, a currently supported platform, has no Rust
| support. Of course the sane response would be "screw NonStop
| then", but having accepted contributions to make NonStop a
| supported platform that isn't an easy path to take.
| AlienRobot wrote:
| Funny, because the average person is convinced it's not worth
| spending any time supporting Linux!
| EasyMark wrote:
| I'm always convinced that people will pick up arbitrary
| projects that they are interested in and might not necessarily
| lead to a new pitch for venture capital or the next unicorn.
| iaaan wrote:
| Lots of interesting use cases for this. First one that comes to
| mind is better interop with other languages, like Python.
| xmodem wrote:
| What does this gain you that you can't already do with `extern
| "c"` functions from rust?
| nicce wrote:
| 'Extern c' still uses Rust. You want to skip Rust and call C
| from other languages directly.
| hypeatei wrote:
| Not GP, but what is the point of touching Rust at all then?
| nicce wrote:
| To generate safer C?
| koakuma-chan wrote:
| Compiling Rust to C doesn't simplify interoperability.
| Either way you'll be calling C functions. I assume
| compiling Rust to C is useful if you're targeting some
| esoteric platform that Rust compiler doesn't support.
| nickpsecurity wrote:
| I'd like to write Rust, receive its safety benefits (esp
| borrow checker), compiler to equivalent C, and then use
| C's tooling on the result. Why use C's tooling?
|
| In verification, C has piles of static analyzers, dynamic
| analyzers, test generators (eg KLEE), code generators (eg
| for parsing), a prover (Frama-C), and a certified
| compiler. If using a subset of these, C code can be made
| more secure than Rust code with more effort.
|
| There's also many tools for debugging and maintenance
| made for C. I can also obfuscate by swapping out
| processor ISA's because C supports all of them. On the
| business end, they may be cheaper with lower watts.
|
| I also have more skilled people I can hire or contract to
| do any of the above. One source estimated 7 million C/C++
| developers worldwide. There's also a ton of books, online
| articles, and example code for anything we need. Rust is
| very strong in that last area for a new language but
| C/C++ will maintain an advantage, esp for low-level
| programming.
|
| These are the reasons I'd use Rust if I wanted C or C++
| for deployment. Likewise, I wish there was still a top-
| notch C++ to C compiler to get the same benefits I
| described with C's tooling.
| koakuma-chan wrote:
| Rust is much easier to learn due to C/C++ books all being
| paid (even cmake wants you to buy their book) whereas
| Rust documentation is free. I bet more and more people
| are choosing to learn Rust over C/C++ for this reason,
| and the number of C/C++ devs will be decreasing.
| cynical_german wrote:
| what a weird take to me... C has DECADES of high quality
| teaching material in form of books, university courses,
| plenty of which is freely available with a bit of
| searching.
|
| And, if we discount the fact that "buying" a book is such
| a big hurdle, even more high quality academic text books
| and papers to boost; anything from embedded on the
| weirdest platforms, basic parsing, writing compilers,
| language design, high performance computing, teaching of
| algorithms, data structures, distributed systems,
| whatever!
|
| edit: I even forgot to name operating system design plus
| game programming ; and of course accompanying libraries,
| compilers & build systems to cover all of those areas and
| use cases! edit2: networking, signal processing,
| automotive, learning about industry protocols and devices
| of any sort... if you explore computer science using C as
| your main language you are in the biggest candy store in
| the world with regards to what it is you want to learn
| about or do or implement...
| koakuma-chan wrote:
| > anything from embedded on the weirdest platforms, basic
| parsing, writing compilers, language design, high
| performance computing, teaching of algorithms, data
| structures, distributed systems, whatever
|
| All that is language-agnostic and doesn't necessarily
| have anything to do with C.
| cynical_german wrote:
| Yes, but there is material covering all of those aspects
| with implementations in C plus libraries plus ecosystem
| support! From teaching material to real world reference
| implementations to look at and modify and learn from.
|
| And C maps so directly to so many concepts; it's easy to
| pick up any of those topics with C; and it being so loose
| makes it even perfect to explore many of those areas to
| begin with, since very quickly you're not fighting the
| language to let you do things.
| koakuma-chan wrote:
| People may learn from material that uses C for
| illustration purposes, but that won't prompt them to
| write their own C. And don't even mention ecosystem
| support in C/C++ where developers are notorious for
| reimplementing everything on their own because there is
| no package manager.
| cynical_german wrote:
| "rust import csv-parser" "you've installed 89 packages"
|
| why is my executable 20 mb, not as performant as a 50 kb
| C file & doesn't build a year later if I try to build
| with 89 new versions of those packages
|
| obligatory xkcd reference:
| https://imgs.xkcd.com/comics/dependency_2x.png this is
| what package managers lead to
| koakuma-chan wrote:
| You are greatly exaggerating the numbers, and Rust and
| its ecosystem are known for being stable. Are you saying
| everyone should write their own csv parser? Also it's
| highly likely that an existing CSV library would be
| optimized, unlike whatever you wrote ad-hoc, so your
| performance argument doesn't hold.
| cynical_german wrote:
| I'm saying package managers automate dependency hell and
| software is and will be less stable & more bloated as a
| consequence. And one should know how to write a csv
| parser and yes, even consider writing one if there are
| obvious custom restraints and it's an important part of
| one's project.
|
| (and yes, numbers were exaggerated; I picked something
| trivial like a csv parser pulling in 89 packages for
| effect; the underlying principle sadly holds true)
| koakuma-chan wrote:
| The number of dependencies does not indicate how bloated
| your app is. Package managers actually reduce bloat
| because your dependencies can have shared dependencies.
| The reason C programs may seem lightweight is because
| their number of dependencies is low, but each dependency
| is actually super fat, and they tend to link dynamically.
| nicce wrote:
| In the context of Rust it is not about "bloat" indeed.
| The compiler includes only used bits and nothing more.
| However, there are other problems, like the software
| supply chain security. More dependencies you have, more
| projects you have to track. Was there a vulnerability
| that affects me? Is project unmaintained and some ill
| factor took it over?
|
| In C this was actually a less problem since you had to
| copy-paste the shared code into your program and at some
| level you were manually reviewing it all the time.
|
| Also in Rust people tend to write very small libraries
| and that increases the number of dependencies. However,
| many still not follow SemVer et. al and packages tend to
| be unstable too. On top of additional security issues.
| They maybe be useful for a short time but in many cases
| you might need to think the lifetime of your application
| up to 10 years.
| koakuma-chan wrote:
| > However, there are other problems, like the software
| supply chain security.
|
| It's not a problem with Rust specifically though. It's
| not unique to Rust.
|
| > Also in Rust people tend to write very small libraries
| and that increases the number of dependencies. However,
| many still not follow SemVer et. al and packages tend to
| be unstable too.
|
| Don't use random unpopular crates maintained by unknown
| people without reviewing the code.
| koakuma-chan wrote:
| Anyone can read a file, split it by newline and split it
| by comma, but what if values contain newlines or commas?
| How do you unescape? What about other edge cases? In Rust
| an existing library would handle all that, and you would
| also get structure mapping, type coercion, validation etc
| for free.
| kstrauser wrote:
| Conversely, "why does my hand-written CSV parser only
| support one of the 423 known variants of CSV, and it
| isn't the one our customer sent us yesterday?"
|
| You kind of have a point behind dependency hell, but the
| flip side is that one needn't become an expert on
| universal CSV parsing just to have a prayer of opening
| them successfully.
| imtringued wrote:
| That applies to your distro package manager too.
| koakuma-chan wrote:
| > C has DECADES of high quality teaching material in form
| of books, university courses, plenty of which is freely
| available with a bit of searching.
|
| Which means all that high quality teaching material is
| DECADES old. Rust development is centralised and
| therefore the docs are always up-to-date, unlike C/C++
| which is a big big mess.
| cynical_german wrote:
| Oh my... Are you serious? I'm almost triggered by this. A
| book about algorithms or data structures from 20 years
| ago has nothing more to teach? 3D game engine design from
| 20 years ago has nothing more to teach? No point in
| looking at the source code of Quake, reading k&r, and
| Knuth's TAOCP Volume 1 was published in 1968 so it's
| obviously irrelevant garbage!
|
| I could spurr into an essay of what kind of lack of
| understanding you just portrayed about the world, but I
| won't.... I won't...
| koakuma-chan wrote:
| We're talking about C/C++, not algorithms or data
| structures.
| jpc0 wrote:
| How you implement algorithms and data structures in
| C++/rust is semantics at best. The imperative shell of
| those languages are identical semantically right down to
| the memory model.
| koakuma-chan wrote:
| Right, that's why a 20 year old book on algorithms and
| data structures is not necessarily outdated, but a 20
| year old book on C/C++ most certainly is.
| ryao wrote:
| Being decades old does not make it out of date. Until a
| few years ago, the Linux kernel was written using C89.
| While it has switched to C11, the changes are fairly
| small such that a book on C89 is still useful. Many
| projects still write code against older C versions, and
| the C compiler supports specifying older C versions.
|
| This is very different than Rust where every new version
| is abandonware after 6 weeks and the compiler does not
| let you specify that your code is from a specific
| version.
| koakuma-chan wrote:
| > Being decades old does not make it out of date.
|
| Right, the docs never get out of date if the thing they
| document never changes. Can you say the same about C++
| though? I've heard they release new versions every now
| and then. My robotics teacher didn't know 'auto' is a
| thing for example.
| jpc0 wrote:
| Auto as it is now has been in C++ since C++11, thats more
| than a decade ago...
|
| If your argument was C then sure thats a C23 feature
| (well the type inference type of auto ) and is reasonably
| new.
|
| This is much more a reflection on youe professor than the
| language. C++11 was a fundamental change to the language,
| anyone teaching or using C++ in 2025 should have an
| understanding of how to to program well in a 14 year old
| version of said language...
| koakuma-chan wrote:
| > Auto as it is now has been in C++ since C++11, thats
| more than a decade ago...
|
| > anyone teaching or using C++ in 2025 should have an
| understanding of how to to program well in a 14 year old
| version of said language...
|
| If the current year is 2025 then 14 years ago is 2011
| which is not that long ago.
|
| > If your argument was C then sure thats a C23 feature
| (well the type inference type of auto ) and is reasonably
| new.
|
| Grandparent comment is arguing that Linux was written in
| C89 until a few days ago so decades old books on C aren't
| actually outdated.
| koakuma-chan wrote:
| > This is very different than Rust where every new
| version is abandonware after 6 weeks and the compiler
| does not let you specify that your code is from a
| specific version.
|
| Do you have any specific evidence? Rust ecosystem is
| known for libraries that sit on crates.io for years with
| no updates but they are still perfectly usable (backward-
| compatible) and popular. Projects usually specify their
| MSRV (minimum supported Rust version) in the README.
| koakuma-chan wrote:
| > edit2: networking, signal processing, automotive,
| learning about industry protocols and devices of any
| sort...
|
| I admit there is many great products that are written in
| C that aren't going anywhere any time soon, notably
| SQLite, but there is no reason to write new software in C
| or C++.
| cynical_german wrote:
| I do, and will, the industry does and will, for at least
| a few more decades. And I even enjoy doing so (with C;
| C++ is more forced upon me, but that'll be the case for
| some time to come)
| koakuma-chan wrote:
| That's what I'm saying. By a few decades you and most of
| those alleged 7 million C/C++ developers will retire and
| there won't be anyone to replace them because everyone
| will be using Rust or Zig or Go.
| quibono wrote:
| Very strong statement, one I don't really believe
| koakuma-chan wrote:
| That's what happened to COBOL, right?
| uecker wrote:
| Probably not. Many people prefer C/C++ to Rust, which has
| its own fair share of problems.
| koakuma-chan wrote:
| Two people is many people. The general trend I see is
| that Rust is exploding in adoption.
| uecker wrote:
| It is, but it is still tiny compared to C/C++. And many
| people also do not like it.
| koakuma-chan wrote:
| There are two categories of people who don't like Rust:
|
| 1. C/C++ developers who are used to C/C++ and don't want
| to learn Rust.
|
| 2. Go developers who claim Rust is too difficult and
| unreadable.
|
| Which one is you?
| icedchai wrote:
| The last I checked various stats (GitHub Language stats,
| TIOBE, etc.), Rust wasn't even in the top 10. I'm sure
| its adoption is increasing. However, other languages like
| Go seem to be doing much better. Neither will replace C++
| or C anytime soon.
| koakuma-chan wrote:
| C/C++ will be replaced incrementally and it's already
| happening. Cloudflare recently replaced nginx with their
| own alternative written in Rust for example.
| icedchai wrote:
| That's nice, but a couple of Rust rewrites are not proof
| of a general trend.
|
| I've been working with C for over 30 years, both
| professionally and a hobbyist. I have experimented with
| Rust but not done anything professionally with it. My gut
| feel is Rust is too syntactically and conceptually
| complex to be a _practical_ C replacement. C++ is also
| has language complexity issues, however it can be adopted
| piecemeal and applied to most existing C code.
| koakuma-chan wrote:
| > That's nice, but a couple of Rust rewrites are not
| proof of a general trend.
|
| It's not just a couple. We've seen virtually all JS
| tooling migrate to Rust, and there is many more things
| but I can't remember by name.
| koakuma-chan wrote:
| > My gut feel is Rust is too syntactically and
| conceptually complex to be a practical C replacement.
|
| That would depend on what you use C for. But I sure can
| imagine people complain that Rust gets in the way of
| their prototyping while their C code is filled with UB
| and friends.
| uecker wrote:
| I think we will get the same safety benefits of Rust in a
| version of C relatively soon.
| koakuma-chan wrote:
| Borrow checker is not the only feature that makes Rust
| great though.
| uecker wrote:
| Yes, it also has many aspects I do not like about it.
| Let's not pretend everybody shares your enthusiasm for
| it.
| koakuma-chan wrote:
| What aspects do you not like about Rust?
| uecker wrote:
| Too much complexity, long build times, monomorphization,
| lack of stability / no standard, poor portability, supply
| chain issues, no dynamic linking, no proper standard, not
| enough different implementations, etc. It is a nice
| language though, but I do not prefer it over C.
| koakuma-chan wrote:
| > long build times, monomorphization
|
| Monomorphization is what causes long build times, but it
| brings better performance than dynamic dispatch.
|
| > lack of stability
|
| There was another comment which also never elaborated on
| how Rust is not stable.
|
| > supply chain issues
|
| Not a language issue, you choose your dependencies.
|
| > no proper standard, not enough different
| implementations
|
| Is that a practical problem?
|
| > no dynamic linking
|
| There is.
| uecker wrote:
| If your like Rust, this is fine, but I will stay with C.
| I find it much better for my purposes.
| dcow wrote:
| Rust doesn't have a runtime so it looks just like C in
| compiled form. c-bindgen even spits out a c header. I'm not
| sure what skipping C practically means even if you can
| argue there's a philosophical skip happening.
| jeroenhd wrote:
| You can't apply _all_ of the hacks C programmers apply,
| like calling private methods, because Rust 's internal
| ABI is different in some annoying spots.
|
| Of course you _shouldn 't_ do that, but it's a problem
| rust-to-c conversion would solve.
|
| Another reason I could think of is the desire to take
| something licensed in a way you don't like, written in
| Rust, for which you'd like to call into the private API
| in your production code, but don't want the legal
| obligations that come with modifying the source code to
| expose the methods the normal way.
|
| I don't think either use case is worth the trouble, but
| there are theoretically some use cases where this makes
| sense.
|
| It's also something I might expect someone who doesn't
| know much about Rust or FFIs outside of their own
| language might do. Not every language supports exporting
| methods to the C FFI, and if you're coming from one of
| those and looking to integrate Rust into your C you might
| think that translation is the only way to do it.
|
| Most likely, it's a way rust haters can use rust code
| without feeling like the "other side" has won.
| pornel wrote:
| The interop is already great via PyO3, except when people want
| to build the Rust part from source, but are grumpy about having
| to install the Rust compiler.
|
| This hack is a Rust compiler back-end. Backends get platform-
| specific instructions as an input, so non-trivial generated C
| code won't be portable. Users will need to either get pre-
| generated platform-specific source, or install the Rust
| compiler and this back-end to generate one themselves.
| chrisrodrigue wrote:
| They are grumpy about having to install the Rust compiler for
| a good reason. You can't compile for Rust on Windows without
| using MSVC via Visual Studio Build Tools, which has a
| restrictive license.
| steveklabnik wrote:
| You can use the GNU ABI instead, if you don't want to use
| the Visual Studio Build Tools.
| estebank wrote:
| https://rust-
| lang.github.io/rustup/installation/windows.html
|
| > When targeting the MSVC ABI, Rust additionally requires
| an installation of Visual Studio so rustc can use its
| linker and libraries.
|
| > When targeting the GNU ABI, no additional software is
| strictly required for basic use. However, many library
| crates will not be able to compile until the full MSYS2
| with MinGW has been installed.
|
| ...
|
| > Since the MSVC ABI provides the best interoperation with
| other Windows software it is recommended for most purposes.
| The GNU toolchain is always available, even if you don't
| use it by default.
| snvzz wrote:
| Excellent.
|
| Now we can quickly re-rustify projects by converting them to C.
| dilawar wrote:
| Is it LLVM IR --> C? Or Rust AST to C?
| dilawar wrote:
| Found the answer in the project readme.
|
| > My representation of .NETs IR maps nicely to C, which means
| that I was able to add support for compiling Rust to C in 2-3K
| LOC. Almost all of the codebase is reused, with the C and .NET
| specific code only present in the very last stage of
| compilation
| nickpsecurity wrote:
| Which might also allow one to use tools that work on .NET
| bytecode. They include verification, optimization, debugging,
| and other transpilers. You might also get a grant or job
| offer from MS Research. :)
| epage wrote:
| It is a rustc backend, ie an alternative to llvm, gcc, or the
| cranelift backends.
|
| It started as a .NET backend but they found that their approach
| could easily support C code generation as well so they added
| that. They do this by turning what rustc gives them into their
| own IR.
| OutOfHere wrote:
| How is this not dangerous? How can one be assured that all of the
| compile-time safety features of the Rust compiler are still in
| effect? Handwaving does not help.
| HeliumHydride wrote:
| It's as safe as LLVM IR is safe, assuming you trust the LLVM IR
| -> C translation step.
| grandempire wrote:
| Because they happen at compile time?
| cv5005 wrote:
| How does the rust compiler assure that when compiling to
| machine code? Machine code is less safe than C after all.
| lmm wrote:
| Machine code is generally much safer than C - e.g. it usually
| lacks undefined behaviour. If you're unsure about how a given
| piece of machine code behaves, it's _usually_ sufficient to
| test it empirically.
| cv5005 wrote:
| Not any different from C - a given C compiler + platform
| will behave completetly deterministically and you can test
| the output and see what it does, regardless of UB or not.
| lmm wrote:
| > a given C compiler + platform will behave completetly
| deterministically and you can test the output and see
| what it does, regardless of UB or not.
|
| Sure[1], but that doesn't mean it's safe to publish that
| C code - the next version of that same compiler on that
| same platform might do something very different. With
| machine code (especially x86, with its very friendly
| memory model) that's unlikely.
|
| (There are cases like unused instructions becoming used
| in never revisions of a processor - but you wouldn't be
| using those unused instructions in the first place.
| Whereas it's extremely common to have C code that looks
| like it's doing something useful, and _is_ doing that
| useful thing when compiled with a particular compiler,
| but is nevertheless undefined behaviour that will do
| something different in a future version)
|
| [1] Build nondeterminism does exist, but it's not my main
| concern
| baq wrote:
| CPUs get microcode updates all the time, too. Nothing is
| safe from bitrot unless you're dedicated to 100%
| reproducible builds and build on the exact same box
| you're running on. (...I'm not, for the record - but the
| more, the merrier.)
| lmm wrote:
| > CPUs get microcode updates all the time, too.
|
| To fix bugs, sure. They don't generally get updates that
| contain new optimizations that radically break existing
| machine code, justifying this by saying that the existing
| code violated some spec.
| carlmr wrote:
| >To fix bugs, sure.
|
| Maybe your program worked due to the bug they fixed.
| lmm wrote:
| Extremely unlikely. CPU bugs generally halt the CPU or
| fail to write the result or something like that. The
| Pentium FDIV bug where it would give a plausible but
| wrong result was a once in a lifetime thing.
| baq wrote:
| Spectre and Meltdown exploits stopped working, too. Some
| of them on some CPUs, anyway.
| uecker wrote:
| It is not terribly hard to generate C code that does not
| use undefined behavior.
| lmm wrote:
| Maybe. But when carefully investigated, the overwhelming
| majority of C code does in fact use undefined behaviour,
| and there is no practical way to verify that any given
| code doesn't.
| uecker wrote:
| No.
| IshKebab wrote:
| Not true on RISC-V. That's full of undefined behaviour.
|
| But anyway this is kind of off-topic. I think OutOfHere was
| imagining that this somehow skips the type checking and
| borrow checking steps which of course it doesn't.
| dzaima wrote:
| What's all that undefined behavior? Closest I can think
| of is executing unsupported instructions, but you have to
| mess up pretty hard for that to happen, and you're not
| gonna get predictable behavior here anyway (and sane
| hardware will trap of course; and executing random memory
| as instructions is effectively UB on any architecture).
|
| (there's a good bit of unpredictable behavior (RVV tail-
| agnostic elements, specific vsetvl result), but
| unpredictable behavior includes any multithreading in any
| architecture and even Rust (among other languages))
| wiseowise wrote:
| How can one be assured that all of the compile-time safety
| features of Java are is still in effect in bytecode?
| RossBencina wrote:
| The JVM class loader verifies the bytecode:
|
| https://stackoverflow.com/questions/755005/how-does-
| bytecode...
| wiseowise wrote:
| It verifies bytecode for bytecode rules violations, not
| that it matches original Java source code or whether
| original source code is safe.
| flomo wrote:
| Of course, everyone votes up the headlines, but this link seems
| like premature WIP. Hopefully this will get posted for real after
| the presentation.
| ay wrote:
| I clicked through to the project at
| https://github.com/FractalFir/rustc_codegen_clr - from a quick
| glance at it, with 1.8k stars and 17 contributors, it deserves
| a better treatment than a passive--aggressive dismissal like
| this as a top comment.
|
| It is a very impressive piece of work.
| flomo wrote:
| Right, and that probably should have been the link rather
| than some in-process thoughts about popcount or w/e. Sorry
| for not figuring it out and clicking around effectively.
| FractalFir wrote:
| The linked article was mostly meant for people already
| lossely familiar with the project, but it seems it escaped
| its intended audience.
|
| I do have a whole bunch of articles about the project on my
| website, going trough the entire journey of the project,
| from its start as a Rust to .NET compiler, to the current
| state.
|
| https://fractalfir.github.io/generated_html/home.html
|
| I should have probably linked the previous articles in this
| one - I'll add that to my website. I'll also look into
| adding some more context to the articles next time.
|
| Thanks for the feedback :)
| flomo wrote:
| I guess the complaint was more about your fans updooting
| stuff, so apologies if it sounded like I was shitting on
| this. Cool project, and I really am awaiting the
| presentation/writeup.
| xmodem wrote:
| Yeah, exactly. Here on a website called 'Hacker News', we're
| only interested in projects when they're feature complete and
| mature enough for production deployment, not before. (/s)
| baq wrote:
| This is Hacker News, not Product Hunt.
| EasyMark wrote:
| If you read the article you'll see this is a status report and
| not a pitch for a final product.
| cod1r wrote:
| this fractalfir person is super talented. See them on the rust
| reddit all the time. I'm not knowledgeable on compilers at all
| but others seem to really like their work.
| landr0id wrote:
| I think they're pretty young too. Hoping for a bright future
| ahead of them!
| jokoon wrote:
| At first I read it as C to rust compiler.
|
| What is the point of compiling rust to C?
| drdeca wrote:
| I think there are probably C compilers for more platforms than
| there are rust compilers. So, if you want to compile your rust
| project on some obscure platform that doesn't have a rust
| compiler for it yet, you could compile to C and then compile
| the resulting C code for that platform?
|
| Just a guess.
| p0w3n3d wrote:
| Exactly. Btw rust toolchain is quite complicated while a code
| that was tanspiled to C might be as well compiled to e.g.
| 6052
| tetha wrote:
| This is a fairly common technique in compiler construction
| and programming language research: Don't try to emit some
| machine code, instead emit C or an IR for clang or GCC. And
| suddenly your little research language (not that rust is one)
| is executable on many, many platforms, can rely on
| optimizations the compilers can do, has potential access to
| debug handling, ..
| kvemkon wrote:
| Vala [1] is, perhaps, the most prominent example of
| practically used programming language with such compiler.
|
| [1]
| https://en.wikipedia.org/wiki/Vala_(programming_language)
| widforss wrote:
| Regarding the other way, I guess a lot of (practically) legal
| C wouldn't compile to Rust at all due to the language's
| restrictions and C's laxness, while I think all Rust could be
| translated to C.
| Someone wrote:
| This project doesn't have that as a goal. In fact, it doesn't
| even have "Rust to C compiler" as a goal.
| https://github.com/FractalFir/rustc_codegen_clr:
|
| _" The project aims to provide a way to easily use Rust
| libraries in .NET. It comes with a Rust /.NET interop layer,
| which allows you to easily interact with .NET code from Rust
|
| [...]
|
| While .NET is the main focus of my work, this project can
| also be used to compile Rust to C, by setting the C_MODE
| enviroment flag to 1.
|
| This may seem like a strange and unrelated feature, but the
| project was written in such a way that this is not only
| possible, but relatively easy."_
|
| It also doesn't mention for which version of C it produces
| code. That may or may not hinder attempts to use this to run
| rust on obscure platforms.
| arka2147483647 wrote:
| The article mentions ANSI-C at places. So seems like the
| old c standard is targeted.
| FractalFir wrote:
| The README is slightly out of date, sorry. Supporting old
| platforms is one of the goals.
|
| Truth be told, the support for C was at first added as a
| proff-of-concept that a Rust to C compiler is possible. But
| it worked surprisingly well, so I just decided to roll with
| it, and see where it takes me.
|
| My policy in regards to C version is: I want to be as close
| to ANSI C as possible. So, I avoid modern C features as
| much as I can. I don't know if full compatibility is
| achievable, but I certainly hope so. Only time will tell.
|
| Some simpler pieces of Rust work just fine with ANSI C
| compilers, but more complex code breaks(eg. due to
| unsupported intrinsics). If I will be able to solve that(+
| some potential soundness issues) then I'll be able to use
| ANSI C.
| teo_zero wrote:
| > What is the point of compiling rust to C?
|
| To address platforms that don't support Rust. TFA mentions
| NonStop, whatever it is.
| vbitz wrote:
| Fault-Tolerant mainframe type systems.
|
| https://en.m.wikipedia.org/wiki/NonStop_(server_computers)
| steveklabnik wrote:
| Not only does NonStop not support Rust, but apparently they
| failed to port gcc to it, even. So compiling Rust straight to
| C itself is pretty much the only option there.
| nickpsecurity wrote:
| They are amazing machines designed for fault tolerance
| (99.999% reliability). The Wikipedia article below has design
| details for how many generations were made. HP bought them.
|
| https://en.m.wikipedia.org/wiki/Tandem_Computers
|
| I think it would be useful in open-source, fault tolerance to
| copy one of their designs with SiFive's RISC-V cores. They
| could use a 20 year old approach to dodge patent issues.
| Despite its age, the design would probably be competitive,
| maybe better, than FOSS clusters on modern hardware in fault
| tolerance.
|
| One might also combine the architecture with one of the
| strong-consistency DR'S, like FoundationDB or CochroachDB,
| with modifications to take advantage of its custom hardware.
| At the _local_ site, the result would be easy scaling of a
| system whose nodes appeared to never fail. The administrator
| still has to do regular maintenance, though, as the system
| reports component failures which it works around.
| arghwhat wrote:
| Using C compiler infrastructure, taking Rust where rustc/llvm
| does not go. Proprietary platforms with proprietary compilers
| for example.
| oulipo wrote:
| I guess it's to target platforms (like some microcontrollers)
| which don't yet have a native Rust compiler, but often do have
| a C compiler?
| vblanco wrote:
| Game consoles generally only offer clang as a possibility for
| compiler. If you can compile rust to C, then you can finally
| use rust for videogames that need to run everywhere.
| dcow wrote:
| I don't think I've ever heard those two terms "video game"
| and "run everywhere" in the same sentence. Bravo.
| koakuma-chan wrote:
| Is Steam Deck a monopoly yet? I feel like if your game
| compiles to Linux, you can target pretty much every market
| out there.
| jeroenhd wrote:
| To use rust in places where you can only use C. I imagine there
| are quite a few obscure microcontrollers that would benefit
| greatly from this pipeline.
|
| Hell, you might finally be able to get Rust into the Linux
| kernel. Just don't tell them the code was originally written in
| Rust to calm their nerves.
| pixelfarmer wrote:
| If I see something like "At least on Linux, long and long long
| are both 64 bits in size." my skin starts to crawl. Not only
| that, but GCC defines __builtin_popcount() with _unsigned_ int /
| long / long long, respective, i.e. even in the text it should be
| mentioned correctly (unless a different compiler uses signed
| types there ... ugh). The call is done with unsigned, using
| uint64_t as a type-cast, but using a fixed __builtin_popcountl()
| which translates to unsigned long. There are systems where this
| will fail, i.e. the only safe bet to use here is
| __builtin_popcountll() as this will cover _at least_ 64 bit wide
| arguments.
|
| Also, if a * b overflows within the result type, it is an
| undefined behavior according to the C standard, so this overflow
| check is at least not properly portable, either, and the shown
| code for that is actually buggy because the last A1 has to be A0.
|
| No idea why all that gets me so grumpy today ...
| dlahoda wrote:
| thank for PR. very fast turn around.
| FractalFir wrote:
| Correct me if I am wrong C, unsigned overflow is well-defined -
| at least the GCC manual says so, but I'll have to check the
| standard.
|
| https://www.gnu.org/software/c-intro-and-ref/manual/html_nod...
|
| Since signed multiplication is bitwise-equivalent to unsigned
| multiplication, I use unsigned multiplication to emulate UB-
| free signed multiplication. The signed variant of this overflow
| check is a bit harder to read because of that, but it still
| works just fine.
|
| bool i128_mul_ovf_check(__int128 A0 ,__int128 A1 ){
|
| bb0:
|
| if((A1) != (0)) goto bb1;
|
| return false;
|
| bb1:
|
| return (((__int128)((__uint128_t)(A0) * (__uint128_t)(A1))) /
| (A1)) == (A1);
|
| }
|
| As for using `__builtin_popcountll` instead - you are right, my
| mistake. Thanks for pointing that out :).
|
| I did not use the word "unsigned" before long long for the sake
| of readability - I know that repeating a word so many times can
| make it harder to parse for some folk. The project itself uses
| the correct types in the code, I was just kind of loose with
| the language in the article itself. My bad, I'll fix that and
| be a bit more accurate.
|
| Once again, thanks for the feedback!
| tialaramex wrote:
| Yes, the C and C++ unsigned types are analogous to Rust's
| Wrapping<u8> Wrapping<u16> Wrapping<u32> and so on, except
| that their size isn't nailed down by the ISO document.
| zwnow wrote:
| Why would I use a tool that doesn't pass all tests?
| 01HNNWZ0MV43FF wrote:
| To not write C
| haswell wrote:
| The post is an update on the status of an ongoing project.
|
| > _This is an update on the progress I have made on my Rust to
| C compiler._
|
| > _There still are about 65 tests that need fixing, but they
| all seem to have pretty similar causes. So, fixing them should
| not be too difficult._
| cbmuser wrote:
| I am still waiting for any of the alternative Rust front- or
| backends to allow me to bootstrap Rust on alpha, hppa, m68k and
| sh4 which are still lacking Rust support.
|
| Originally, the rustc_codegen_gcc project made this promise but
| never fulfilled it.
| Aurornis wrote:
| > to allow me to bootstrap Rust on alpha, hppa, m68k and sh4
|
| Do you actually use all four of those platforms, or is this an
| arbitrary threshold for what you consider a complete set of
| platform support?
| im_down_w_otp wrote:
| They're still common (except for alpha) platforms in some
| market segment specific corners of embedded development. So,
| maybe for those purposes?
|
| Though, the trend I'm seeing a lot of is greenfield projects
| just migrating their MCUs to ARM.
| Aurornis wrote:
| > Though, the trend I'm seeing a lot of is greenfield
| projects just migrating their MCUs to ARM.
|
| That's what I would expect, too.
|
| The Venn diagram of projects using an old architecture like
| alpha but also wanting to adopt a new programming language
| is nearly two separate circles.
|
| The parent comment even included HPPA (PA-RISC) which
| almost makes me think they're into either retro computing
| or they have some arbitrary completionist goal of covering
| all platforms.
| CursedSilicon wrote:
| Hi, retro computing person here. I've had a similar
| debate with Rust evangelists in past
|
| Something the Rust community doesn't understand is when
| they shout "REWRITE IT IN RUST!" at a certain point
| that's simply _not possible_
|
| Those mainframes your Bank runs? I'm sure they'd love to
| see all that "awful" FORTRAN or C or whatever other
| language rewritten in Rust. But if Rust as a platform
| doesn't support the architecture? Well then that's a non-
| starter
|
| Worse still, Rust seems to basically leave anything that
| isn't i686/x86_64 or ARM64 as "Tier 2" or worse
|
| This specific line in Tier 2 would send most project
| managers running for the hills "Tier 2 target-specific
| code is not closely scrutinized by Rust team(s) when
| modifications are made. Bugs are possible in all code,
| but the level of quality control for these targets is
| likely to be lower"
|
| Lower level of quality control when you're trying to
| upgrade or refactor a legacy code base? And the target is
| a nuclear power plant? Or an air traffic control system?
| Or a bank?
|
| The usual response from the Rust evangelists is "well
| then they should sponsor it to run better!" but the
| economics simply don't stack up. Why hire 50 Rust
| programmers to whip rust-m68k into shape when you can
| just hire 10 senior C programmers for 20% of the cost?
|
| EDIT: Architecture, not language. I need my morning
| coffee
| dralley wrote:
| >Those mainframes your Bank runs? I'm sure they'd love to
| see all that "awful" FORTRAN or C or whatever other
| language rewritten in Rust. But if Rust as a platform
| doesn't support the architecture? Well then that's a non-
| starter
|
| But Rust does support S390x?
|
| >Worse still, Rust seems to basically leave anything that
| isn't i686/x86_64 or ARM64 as "Tier 2" or worse
|
| Rust has an explicit documented support tier list with
| guarantees laid out for each level of support. Point me
| to a document where GCC or Clang lists out their own
| explicit guarantees on a platform-by-platform basis.
|
| Because I strongly suspect that the actual "guarantees"
| which GCC, clang and so forth provide for most obscure
| architectures is not that much better than Rust, if at
| all - just more ambiguous. And I don't find it very
| likely that the level of quality control for C compilers
| on m68k or alpha or s390x is not, in practice, at least a
| bit lower than that provided for x86 and ARM.
| im_down_w_otp wrote:
| We made s390x builds of all our tools
| (http://www.auxon.io) for an early customer that insisted
| on running their org on a leased machine from IBM.
|
| It was actually a pretty good experience. It mostly just
| worked.
| woodruffw wrote:
| > This specific line in Tier 2 would send most project
| managers running for the hills "Tier 2 target-specific
| code is not closely scrutinized by Rust team(s) when
| modifications are made. Bugs are possible in all code,
| but the level of quality control for these targets is
| likely to be lower"
|
| Are you operating under the assumption that the largely
| implicit support tiers in other compilers are better? In
| other words: do you think GCC's m68k backend (to pick an
| arbitrary one) has been as battle-tested as their AArch64
| one?
|
| (I think the comment about evangelists is a red herring
| here: what Rust does is offer _precison_ in what it
| guarantees, while C as an ecosystem has historically been
| permissive of mystery meat compilers. This IMO doesn't
| scale well in a world where project maintainers are
| trivially accessible, since they have to now field bug
| reports on platforms they can't reproduce for and never
| intended to support to begin with.)
| fintler wrote:
| > do you think GCC's m68k backend (to pick an arbitrary
| one) has been as battle-tested as their AArch64 one
|
| m68k might be a bad example to pick. I was using gcc to
| target m68k on netbsd in the mid 1990s. It's very battle
| tested.
|
| Also, don't forget that m68k used to be in all of the
| macs that Apple sold at one point before they switched to
| powerpc (before switching to x86 and the current arm
| chips). You could use gcc (with mpw's libs and headers)
| on pre-osx (e.g. system 7) m68k macs.
| woodruffw wrote:
| > m68k might be a bad example to pick. I was using gcc to
| target m68k on netbsd in the mid 1990s. It's very battle
| tested.
|
| That was 30 years ago! Having worked on LLVM: it's _very_
| easy for optimizing compilers to regress on smaller
| targets. I imagine the situation is similar in GCC.
|
| (The underlying point is simpler: explicit is better than
| implicit, and all Rust is doing is front-loading the
| frustration from "this project was never tested on this
| platform but we pretend like it was" to "this platform is
| not well tested." That's a good thing.)
| hedgehog wrote:
| Did they abandon that goal? Last I heard it was still under
| development.
| shakna wrote:
| "m68k-unknown-linux-gnu" was merged as a Tier-3 target for
| Rust, wasn't it? [0]
|
| [0] https://github.com/rust-lang/compiler-team/issues/458
| jedisct1 wrote:
| rust still doesn't even support OpenBSD on x86_64...
| mrweasel wrote:
| Do you mean x86 (as in 32bit)? Because I'm fairly sure that
| there's a Rust package available on x86_64 ( and aarch64,
| riscv64, sparc64 and powerpc64).
| dralley wrote:
| Rust has Tier 3 support for OpenBSD on x86_64
| jedisct1 wrote:
| Nim to C compiler, 100% test pass rate.
| alexpadula wrote:
| Rust to C? Why would someone do that. Just write C.. if you can
| figure rust out you surely can figure C out and be proficient.
| alexpadula wrote:
| I will read further into the project just off the bat I don't
| get the point. Good luck it looks quite extensive :)
| AS04 wrote:
| Because of the niceties of Rust, combined with the widespread
| compatibility and architecture support of gcc / C compilers in
| general?
|
| Rust is a modern language, with package management, streamlined
| integrated build/testing tools, much less cruft, and lots of
| high-level features and syntax that people actually like. C is
| neat but complex codebases benefit from modern languages that
| help in building robust abstractions while still maintaining
| the speed of C. _Not to mention, of course, the borrow checker
| and memory safety._
| AlotOfReading wrote:
| So you can get the benefits of Rust on platforms that rustc
| doesn't support. Seems pretty straightforward.
| wolrah wrote:
| It seems like there's a healthy dose of "because it can be
| done" in play here, but also because there are a lot of
| platforms that are not supported by Rust where a Rust-to-C
| converter that generated standard-enough code could be used to
| bridge the gap.
| nullpoint420 wrote:
| Would it be possible for Rust to output LLVM IR? Would that make
| it easier to port if they have a LLVM frontend?
| guipsp wrote:
| This comment is strange, given that LLVM is rust's most mature
| backend
| woodruffw wrote:
| I think the GP means emit LLVM IR directly. And the answer to
| that is yes; you can pass a flag to rustc that will emit the
| IR[1].
|
| [1]: https://stackoverflow.com/questions/39004513/how-to-
| emit-llv...
| 1vuio0pswjnm7 wrote:
| "Most components of std are about 95% working in .NET, and 80%
| working in C."
|
| .NET
|
| Core tests 1662 39 12 97.02%
|
| C
|
| Core tests 1419 294 82.83%
|
| Missing from HN title: The "95%" pass rate only applies to .NET.
| For GCC/Clang it is only "80%".
___________________________________________________________________
(page generated 2025-04-12 23:02 UTC)