[HN Gopher] Translating Quake 3 into Rust
       ___________________________________________________________________
        
       Translating Quake 3 into Rust
        
       Author : K0nserv
       Score  : 323 points
       Date   : 2020-01-07 13:07 UTC (9 hours ago)
        
 (HTM) web link (immunant.com)
 (TXT) w3m dump (immunant.com)
        
       | kstenerud wrote:
       | That's super cool!
       | 
       | What I'd really like to see is benchmarks that compare the rust
       | version to C.
        
         | rinon wrote:
         | We didn't benchmark this project (yet) but previous c2rust
         | translations had approximately equal performance to the
         | original. This is to be expected since the transpiled output is
         | unsafe Rust that is equivalent to the original C code. One
         | caveat is checked va unchecked array indexing, but unless an
         | array indexing operation into a statically sized array is hot
         | _and_ the Rust compiler can't elide the checks, that's unlikely
         | to make much of a difference.
        
         | AdmiralAsshat wrote:
         | What is the realistic best-case scenario? Has anyone
         | demonstrated that well-written Rust code should run _faster_
         | than C, or is the hope simply to get performance parity with C
         | while maintaining memory safety?
        
           | [deleted]
        
           | seren wrote:
           | Not answering directly your question, but I remember seeing a
           | benchmark recently where there was more difference in
           | performances for a program compiled with gcc and clang, than
           | between the C++ clang and Rust performances.
           | 
           | So I believe that when you are that close in term of
           | performances, you can assume that they all have the same
           | performance, and that it should not be a decision driver
           | whatsoever.
        
           | vmchale wrote:
           | rustc and gcc are not the same compiler. Languages are hard
           | to compare...
        
             | dodobirdlord wrote:
             | True, but gcc isn't the only C compiler, and these days
             | clang, which is an LLVM frontend like rustc, is pretty
             | popular and mostly equivalent to gcc.
        
               | vmchale wrote:
               | In my experience, there have been times rustc
               | underperformed relative to both gcc _and_ clang.
               | 
               | In the past performance infelicities have been fixed, but
               | there are some that remain.
        
           | K0nserv wrote:
           | Yes, the most recent example I can think of is
           | http://cliffle.com/p/dangerust/ in which the author
           | translates heavily optimized C to Rust in a quite mechanical
           | way. It comes out being slightly faster. In the last part
           | they rewrite it in idomatic Rust and it ends up even faster
           | again without any of the bespoke optimizations that the C
           | code used or any unsafe Rust.
           | 
           | In many instances the Rust type system should allow the
           | compiler to emit faster code because it has more data to use
           | for reasoning about valid and invalid states of the program.
           | Depending on how good c2rust is the Rust version should be
           | roughly as fast, refactored to idomatic Rust it could be
           | meaningfully faster than C.
        
           | almindor wrote:
           | Rust will outperform C consistently soon. It already does in
           | some cases. It will also do so with safe idiomatic code in
           | most cases. The reason behind my statement is simply more
           | opportunity for the optimizer. Rusts rules allow for a more
           | aggressive optimization. The reasons why it's not
           | outperforming C yet are LLVM bugs and some missing Rust
           | language features and fixes. LLVM in particular is driven by
           | C needs so they rarely fix bugs present only Rustc generated
           | IR.
        
             | mhh__ wrote:
             | What rules, is pointer aliasing enough?
             | 
             | The backends are getting so complicated now that I'm not
             | sure low level languages can make that much difference
             | assuming they generate clean IR.
        
             | dodobirdlord wrote:
             | This is grey, but shouldn't be. I assume people are downing
             | it because it doesn't give examples of the optimization
             | opportunities it claims. So here are two that I think are
             | likely most significant.
             | 
             | 1. Rust's aliasing semantics are more powerful than C's
             | unless you use the 'restrict' keyword everywhere, which
             | most people don't. It's well recognized that FORTRAN
             | continues to generally outperform C in many numeric
             | applications because FORTRAN compilers are free to perform
             | optimizations that C compilers cannot or don't, due to the
             | fact that multi-aliasing memory is undefined behavior in
             | FORTRAN. The rust compiler currently doesn't pass the
             | relevant hints to the generated LLVM IR due to a long
             | history of LLVM having bugs in 'noalias' handling, in large
             | part due to the fact that those code paths are so rarely
             | executed while compiling C code, itself due to the
             | relatively low usage of the 'restrict' keyword.
             | 
             | 2. Implicit arena allocations. The Rust compiler has access
             | to information about possible aliasing and overlapping
             | lifetimes that it can use to replace multiple allocations
             | with similar lifetimes with offsets into a single
             | allocation that is then all freed together. This is a
             | complicated topic, but work is ongoing to make this a
             | reality.
        
               | mrec wrote:
               | > _work is ongoing to make [implicit arena allocations] a
               | reality._
               | 
               | Ooh, interesting; I hadn't heard about that but it makes
               | a lot of sense. Do you happen to have an RFC or issue
               | link? My google-fu is failing me.
        
             | vmchale wrote:
             | rustc still has a number of cases where it performs poorly
             | compared to gcc and even clang
        
           | steveklabnik wrote:
           | This topic is really tricky, and there's a _lot_ of different
           | ways to slice it. In the most general sense, if you take a C
           | expert, and a Rust expert, and ask them to do something, they
           | should be able to get the exact same results.
           | 
           | But that leaves out other interesting questions that inform
           | this comparison. For example:
           | 
           | * What about the _average_ Rust programmer vs the average C
           | programmer? Maybe two experts can produce identical results,
           | but does one language vs the other make it so that a non-
           | expert tends to produce faster code?
           | 
           | * What about "no unsafe Rust other than what's in the
           | implementation of the standard library"? Most Rust code
           | doesn't use unsafe, so is it fair to let the Rust use it? How
           | much?
           | 
           | * What about "no code other than the standard libraries." I
           | may not be an expert, but Rust's package ecosystem makes it
           | easier to use code that's developed by them. This is sort of
           | a slightly different take on the two previous questions at
           | the same time.
           | 
           | * Should there be a time limit on development? If so, should
           | the C have the same requirements of demonstrating safety as
           | the Rust, that is, sketching out an informal proof of
           | correctness?
           | 
           | * What about some sort of "how maintainable is this" metric.
           | Mozilla tried to implement parallel CSS in C++ twice, and
           | couldn't do it, because the concurrency bugs were just too
           | many. Their Rust attempt succeeded, thanks to the safety
           | guidelines. Is this comparison valid? Or could some sort of
           | person who was better at C++ have implemented it in theory
           | with no bugs? (this is sort of question 1, but slightly
           | different.)
           | 
           | Lots and lots of ways to do this.
        
             | weberc2 wrote:
             | I think it would be particularly interesting to compare
             | idiomatic Rust and C code. For example, given C's lack of
             | generics, I would expect Rust to have a number of wins,
             | including better inlining opportunities for polymorphic
             | functions a la qsort.
        
             | mlindner wrote:
             | I'd also add that there's LLVM bugs that prevent Rust from
             | getting faster.
             | 
             | https://stackoverflow.com/questions/57259126/why-does-the-
             | ru...
             | 
             | Theoretically I would argue that Rust could get faster than
             | C, because it can make stronger guarantees about the code
             | that would allow further and much more complex
             | optimizations of the code. You could argue that the set of
             | possible outputs of a piece of C code is much wider than a
             | piece of Rust code and you could compile the code down to
             | some sort of state machine that equivalently represents the
             | original code in a more compact form. The more well defined
             | the outputs are, the more minimal the output representation
             | could be.
        
           | masklinn wrote:
           | > What is the realistic best-case scenario?
           | 
           | Finding latent logic and memory errors, gaining greater
           | confidence, security and velocity.
           | 
           | > Has anyone demonstrated that well-written Rust code should
           | run faster than C
           | 
           | Should? No. Can? Yes. See Brian Cantrill's
           | http://dtrace.org/blogs/bmc/2018/09/28/the-relative-
           | performa... or Cliff Biffle's http://cliffle.com/p/dangerust/
        
             | vintermann wrote:
             | There are some "shoulds" related to aliasing I believe.
             | Things the compiler can assume when compiling a rust
             | program that it can't when compiling C, which should in
             | theory let it generate more efficient code.
             | 
             | But last I heard Rust wasn't taking advantage of this due
             | to issues with LLVM. The same benefits should also be
             | achievable in C with pragmas.
        
               | masklinn wrote:
               | > There are some "shoulds" related to aliasing I believe.
               | 
               | c2rust has to be careful not to "restrict" pointers which
               | can in fact alias.
               | 
               | > But last I heard Rust wasn't taking advantage of this
               | due to issues with LLVM.
               | 
               | That's correct: https://github.com/rust-
               | lang/rust/issues/54878
               | 
               | > The same benefits should also be achievable in C with
               | pragmas.
               | 
               | I don't know that any compiler provides a noalias-all
               | pragma. I don't know that it would be very sane either
               | since C very much defines pointers as aliasing by
               | default. Plus you wouldn't have any way to revert this
               | behaviour and mark pointers as aliasing.
        
         | steveklabnik wrote:
         | Benchmarks would be interesting, in the sense that it would
         | help make sure that the translation is doing the same thing,
         | but it wouldn't say a ton about Rust vs C in a more general
         | case. This translates to unsafe code, which means it's not
         | really representative of Rust generally.
        
       | [deleted]
        
       | [deleted]
        
       | faebi wrote:
       | Does it mean we could translate languages like Ruby and Python to
       | Rust?
        
         | johannes1234321 wrote:
         | Technically it is possible. The gain won't be there for most
         | cases, though as the generated code would be complex and bad as
         | variables often have to be carried as "variant" types and you
         | have to plug in to the library (which has a specific C API) and
         | so on.
         | 
         | Facebook for some time did this with their "HipHop for PHP"
         | transpiler which translates PHP into C++ and then fed it to
         | gcc. That worked, but due to all the type conversion and
         | similar magic required on all calls this lead them to
         | compilation times of 24 hours and interfaces which were hard to
         | interact with for language bindings, thus they went back to
         | write a scripting engine (HHVM) which now runs their forked
         | PHP.
        
         | K0nserv wrote:
         | While it might be possible my guess is it would be much more
         | difficult than C. AFAIK Rust is more or less a superset of C
         | whereas Python and Ruby have numerous advanced features that
         | aren't present in Rust and would likely require a bespoke Rust
         | runtime to emulate the behaviour. Types is also a whole can of
         | worms here.
         | 
         | I think in relation to Ruby, Python and other languages like
         | them Rust's best application is leveraging the support for C
         | FFIs to replace hot paths. While Rust has a significant
         | learning curve it's probably much simpler, for say a ruby
         | programmer, to pick it up and write safe performant code than
         | C.
        
       | ahomescu1 wrote:
       | Author here: I wanted to let everyone know we made some small
       | edits to the text, and added two new branches to our repository:
       | _transpiled_ containing the raw transpiler output [1], and
       | _refactored_ containing the same code [2] after a few refactoring
       | commands.
       | 
       | 1. https://github.com/immunant/ioq3/tree/transpiled/quake3-rs
       | 
       | 2. https://github.com/immunant/ioq3/tree/refactored/quake3-rs
        
       | bbmario wrote:
       | Is the final code readable/maintainable?
        
         | steveklabnik wrote:
         | There's an example of the output and a discussion of this
         | elsewhere in this thread. TL;DR: not as much as it could be,
         | yet. This is a work in progress.
        
         | ahomescu1 wrote:
         | We added the transpiled code in a new branch at
         | https://github.com/immunant/ioq3/tree/transpiled/quake3-rs and
         | also a more cleaned up refactored code base at
         | https://github.com/immunant/ioq3/tree/refactored/quake3-rs
        
         | edflsafoiewq wrote:
         | No.
        
       | tombert wrote:
       | Out of curiosity, has anyone here tried taking something like
       | Quake 2 or 3 and porting it to run on the JVM?
       | 
       | This project kind of makes me want to try porting Quake 3 into
       | Clojure, but I want to know the limitations in doing so.
        
         | cartoonfoxes wrote:
         | https://bytonic.de/html/jake2.html
        
           | tombert wrote:
           | Oh neat; I'll have to look at this tonight....thanks!
        
             | strbean wrote:
             | Jake2 is what Google used (+ GWT) to get Quake2 in the
             | browser as one of the more impressive early WebGL demos:
             | 
             | https://code.google.com/archive/p/quake2-gwt-port/
        
         | cs02rm0 wrote:
         | I'd imagine the graphics libraries is where the JVM falls down.
        
           | pjmlp wrote:
           | Java is even one of the managed languages that already has
           | Vulkan bindings.
           | 
           | Java history is full of OpenGL and DirectX bindings as well.
           | 
           | Just not all of them have survived the original authors
           | leaving the project.
           | 
           | Before Unity was a thing, Java already had the Java Monkey
           | Engine.
        
           | [deleted]
        
           | agumonkey wrote:
           | Cant one bind to opengl directly ?
        
             | p1necone wrote:
             | Yes you can. Java works fine for even kinda high end 3d
             | graphics, not many people do it though.
             | 
             | The biggest thing in java gamedev is avoiding GC pauses.
        
               | tombert wrote:
               | I would think that with the newer GCs (like Shenandoah)
               | for Java, the GC pause thing might become a non-issue
               | soon enough. Not sure that works for Clojure though.
        
           | flatiron wrote:
           | Not that Minecraft runs well or is a marvel of graphical
           | technology but at least it proves you can do FPS 3D with the
           | JVM enough to the the most popular game around.
        
             | phit_ wrote:
             | Minecraft uses https://www.lwjgl.org/
        
       | arendtio wrote:
       | I would love to see them translating the Linux kernel, but that
       | might be a bit too ambitious.
        
       | jtaft wrote:
       | This is some awesome PR too! Didn't expect them to be a software
       | security consultancy.
        
         | steveklabnik wrote:
         | Some of this work was even funded by DARPA...
        
       | johnklos wrote:
       | Why is there such a push to use this new language that's so
       | inaccessible to much of the world? Not everyone has a multi-
       | gigahertz, multi-core, multi-gigabyte computer to develop in
       | Rust. It seems like unnecessary stratification for nebulous gain.
       | 
       | Perhaps the Rust team should make their compiler work on
       | reasonable resources, like 32 bit processors, before marching off
       | to try to convert the world.
       | 
       | Or perhaps we should have rust2c instead, so people can take all
       | this Rust code that everyone is pushing and compile it on modest
       | machines.
        
         | p1necone wrote:
         | > "multi-gigahertz, multi-core, multi-gigabyte"
         | 
         | Unless you're talking about people holding on to hardware from
         | 20+ years ago then yes - basically everyone with a computer, or
         | a mobile phone has something that fits that classification.
         | 
         | People complain about Rust having long compile times, but I
         | doubt it would be _unusably_ bad even on something like a core
         | 2 duo.
        
         | zozbot234 wrote:
         | Even some large C++ projects are becoming hard or perhaps
         | impossible to build using a 32-bit compiler. It's not something
         | that only hits Rust.
        
         | twblalock wrote:
         | > Perhaps the Rust team should make their compiler work on
         | reasonable resources, like 32 bit processors, before marching
         | off to try to convert the world.
         | 
         | It's time to let 32-bit processors go and move on.
        
           | [deleted]
        
           | AceJohnny2 wrote:
           | There are magnitudes more processors out there than desktop-
           | or server-class.
        
             | tverbeure wrote:
             | How many of those processors are used to compile code?
             | 
             | The complaint above is about that. Running compiled Rust
             | code on a tiny embedded microcontroller is not a problem.
             | 
             | https://medium.com/coinmonks/coding-the-stm32-blue-pill-
             | with...
        
         | vmchale wrote:
         | > Why is there such a push to use this new language that's so
         | inaccessible to much of the world?
         | 
         | Eh?
        
         | elihu wrote:
         | Poor computer security poses an existential threat to modern
         | civilization. Slow-ish compile times do not.
        
           | hinkley wrote:
           | I'd heard that the Rust compiler can't compile itself on a 32
           | bit machine with maxed out RAM.
           | 
           | I know there have been some changes to shrink memory usage
           | for a bunch of data types in Rust but it's not clear if that
           | has changed this limitation.
           | 
           | I'm trying to learn Rust now, and one of my eventual goals is
           | to look into heap analysis of the compiler, because I agree
           | this is some bullshit.
           | 
           | I want to run stuff on ARM eventually and cross compilation
           | and transfer don't sound like my idea of a good time.
        
             | steveklabnik wrote:
             | This is not entirely a rustc issue; LLVM is a huge part of
             | this as well. Sometimes, some steps need more than four
             | gigs of RAM. loc says that rustc has 1.4 million lines of
             | Rust, and LLVM has 5 million of C++. It's just a huge
             | project.
             | 
             | In the past, people have reported these things, and we've
             | tried to fix or help where possible; see the discussion on
             | https://github.com/rust-lang/rust/issues/60294 for example.
        
         | antpls wrote:
         | > Not everyone has a multi-gigahertz, multi-core, multi-
         | gigabyte computer to develop in Rust.
         | 
         | Even low-end Android phones have multi-gigahertz, multi-core,
         | multi-gigabyte memory, so actually, many people have that in
         | their pockets
        
         | AceJohnny2 wrote:
         | > _Perhaps the Rust team should make their compiler work on
         | reasonable resources, like 32 bit processors_
         | 
         | Rust compiles for and runs on STM32, a 32-bit microcontroller:
         | 
         | https://docs.rust-embedded.org/discovery/
         | 
         | And here's an index of supported embedded hardware:
         | 
         | https://github.com/rust-embedded/awesome-embedded-rust#drive...
        
           | andai wrote:
           | _> Perhaps the Rust team should make their compiler work on
           | reasonable resources, like 32 bit processors_
           | 
           |  _> Rust compiles for and runs on STM32, a 32-bit
           | microcontroller_
           | 
           | Cool, but it can't run the _compiler,_ right? I think that 's
           | what GP meant.
        
           | monocasa wrote:
           | He's saying for running the compiler, not for the compilation
           | target I think.
        
         | tracker1 wrote:
         | First, rust provides safety checks you don't get in C. Second,
         | the only way you'd improve compiler performance via C
         | conversion would bypass these checks. Third, transpiling
         | through C without these safety checks loses the point of rust
         | in the first place.
         | 
         | The fact is, that there are a great many bugs in the wild that
         | never would have happened in idiomatic rust in the first place.
         | Yes, there is additional overhead to compiling. By comparison,
         | if you use static code analysis on your C/C++ code there is
         | additional overhead, and even then a greater chance of security
         | bugs slipping by compared to rust.
         | 
         | In the end, used server hardware is relatively cheap in most of
         | the world, which does pretty well with this type of code. There
         | are a lot of people using mid-upper range x86 hardware and even
         | to cross-platform compile to lower end arm64 support. At some
         | point, it's less worth maintaining legacy hardware either for
         | pragmatic and/or practical reasons.
         | 
         | Rust was started well after x64 and other 64-bit hardware was
         | in the wild, and 32-bit hardware was for the most part no
         | longer being produced. Supporting such systems is work that
         | practically speaking is less valuable to most people.
         | 
         | As someone that really likes the old DOS based BBS software and
         | related tech, and even supports Telnet BBSes today, I don't
         | always like seeing this left behind to some extent. Last year,
         | a large portion of the community blew up when 32bit was going
         | to be dropped from Ubuntu, mainly because of the need required
         | by wine and the gaming community.
         | 
         | This isn't about supporting 10+ year old apps and programs in
         | an emulated environment... this is about porting existing code
         | in an automated enough way to improve stability and support-
         | ability over time by leveraging a safer language.
        
         | smolder wrote:
         | The compiler performance may be a perfectly valid reason not to
         | use Rust. Don't mistake the frequent Rust articles for the
         | whole world moving to Rust. It's more like a few excited
         | pioneers exploring its use cases and doing foundational work.
         | Besides, if it helps other people build more stable, secure, or
         | better performing software tools for you to use, isn't that
         | good, even if you don't use it directly yourself?
        
         | steveklabnik wrote:
         | We distribute binaries of the compiler for a bunch of 32 bit
         | targets. It will of course be slower on slower machines, but
         | that's just physics.
         | 
         | mrustc is "rust to C", though it's not quite ready for the
         | general case yet. It's primarily for translating the compiler,
         | to ease bootstrapping.
        
       | wyldfire wrote:
       | I recall seeing a presentation of c2rust by Andrei at a
       | conference a while back. It's great to hear that it's making good
       | progress. I'm curious at how good c2rust is at producing
       | idiomatic rust code. It seems like that would be difficult and
       | yet very valuable.
       | 
       | > we'd love to hear what you want to see translated next.
       | 
       | qemu [1] is all in C (probably C89 or "gnu89") and would make an
       | interesting project, IMO.
       | 
       | [1] https://github.com/qemu/qemu
        
         | K0nserv wrote:
         | I looked for the transpiled source, but I couldn't find it. I
         | suspect it's not particularly idomatic Rust since it has to
         | maintain all details of the C code however I think it's a very
         | promising project anyway.
         | 
         | The fact that they found a memory safety bug is excellent.
         | Maybe translating old C projects to Rust via this method can be
         | used to find memory issues as well as to aid rewriting in Rust
         | projects.
         | 
         | EDIT: You can try the transpilation yourself on
         | https://c2rust.com/
         | 
         | Here's an example of the output:
         | #![allow(dead_code, mutable_transmutes, non_camel_case_types,
         | non_snake_case,                  non_upper_case_globals,
         | unused_assignments, unused_mut)]
         | #![register_tool(c2rust)]         #![feature(register_tool)]
         | #[no_mangle]         pub unsafe extern "C" fn insertion_sort(n:
         | libc::c_int, p: *mut libc::c_int) {             let mut i:
         | libc::c_int = 1 as libc::c_int;             while i < n {
         | let tmp: libc::c_int = *p.offset(i as isize);
         | let mut j: libc::c_int = i;                 while j > 0 as
         | libc::c_int &&                           *p.offset((j - 1 as
         | libc::c_int) as isize) > tmp {                     *p.offset(j
         | as isize) =                         *p.offset((j - 1 as
         | libc::c_int) as isize);                     j -= 1
         | }                 *p.offset(j as isize) = tmp;
         | i += 1             };         }
        
           | steveklabnik wrote:
           | Their plan is twofold, in my understanding: first to
           | translate the code fairly literaly, and then second, to
           | provide unsafe -> safe refactoring tools. As far as I know
           | they're still on step 1.
        
             | mikepurvis wrote:
             | Looks like it's meant to enable projects similar to how the
             | Go compiler/toolchain was initially translated (with the
             | like-named c2go) and then gradually rewritten over time
             | into idiomatic golang. It's easy to see that this could be
             | a much more tenable project then a grand rewrite that has
             | two codebases iterating forward in parallel for a time.
        
             | K0nserv wrote:
             | Cool, that seems like a very sensible approach. The fact
             | that they are already uncovering memory issues in C is
             | promising too.
        
               | steveklabnik wrote:
               | Yep, I think so too. That example output is more verbose
               | than a human would write, but it's a sensible start.
        
             | harpocrates wrote:
             | Step 2 has been happening concurrently, and pretty much
             | since the start of the project. See
             | https://github.com/immunant/c2rust/tree/master/c2rust-
             | refact.... It is just a lot tougher to get right, so it
             | gets less publicity.
        
               | steveklabnik wrote:
               | Ah awesome! Thanks for the link.
        
         | masklinn wrote:
         | > I'm curious at how good c2rust is at producing idiomatic rust
         | code.
         | 
         | It's not. It should eventually improve but currently the goal
         | is to
         | 
         | > build a rock-solid translator that gets people up and running
         | in Rust.
        
           | weberc2 wrote:
           | What is the ceiling for how good (i.e., "close to generating
           | idiomatic Rust") it could get? Given the differing semantics,
           | it seems like it should be nearly impossible to generate
           | anything close to idiomatic Rust, but I know very little
           | about mechanically translating between programming languages
           | and I would be delighted to be incorrect.
        
             | masklinn wrote:
             | I'd say "pretty low" on the idiomatic scale, however a very
             | desirable thing would be for them to manage to make most of
             | the generated code _not unsafe_. Limiting the scope of
             | unsafe would make what would remain easier to convert to
             | safe rust, and then you 're off to the refactoring race
             | with much more confidence.
             | 
             | A pretty good go would be the ability to recognise wide-
             | spread high-level C patterns and be able to convert them to
             | idiomatic Rust pattern, but even that would be difficult,
             | generally speaking idiomatic C and Rust would likely be
             | _structured_ quite differently, especially on the
             | data(-structure) side.
        
             | [deleted]
        
         | flohofwoe wrote:
         | Here's an example from another code base, the Linux
         | (GLX+X11+GL) extract of an 3D API wrapper around OpenGL:
         | 
         | https://github.com/not-fl3/miniquad/blob/c2rust/sokol-app-sy...
         | 
         | The generated code looks fairly straightforward, however I
         | wouldn't call it "idiomatic".
         | 
         | What's exciting though is that (at least) both Rust and Zig get
         | this ability to translate C code into the "native" language
         | (and sometimes even finding bugs in the process). This
         | basically turns C into a "meta-language" to create "bedrock"
         | cross-platform API modules for a variety of modern languages,
         | essentially the next step from "C as a cross-platform
         | assembler".
         | 
         | And to be honest, this sort of "boring" low-level system API
         | glue code which mainly talks to native C system APIs anyway
         | isn't a joy to write in any language, and also doesn't benefit
         | much from more modern language features, can just as well do it
         | in C once, and then "transpile everywhere".
        
           | dodobirdlord wrote:
           | This seems pretty contrary to the purpose of Rust, since the
           | generated code is full of non-idiomatic unsafe and possibly
           | situationally unsound pointer manipulations that could
           | definitely be done in idiomatic safe code. No reason I can
           | see not to just write this sort of thing in Rust to begin
           | with and expose it to other languages via the C ABI to call
           | with FFI or even co-compile with other LLVM languages.
        
             | flohofwoe wrote:
             | Yeah theoretically, but then you have the same problem as
             | using C libraries from Rust, the build process for those
             | other languages suddenly becomes much more complicated
             | because they must integrate with another language
             | toolchain.
             | 
             | Lets say I want to expose a Zig library to Rust or vice
             | versa, now I must call the Zig compiler from Cargo, or
             | Cargo from the Zig build process.
             | 
             | With a transpiled library such a project is "clean", it
             | only needs the Rust or Zig toolchain. The transpiling
             | process only needs to happen once, and this can happen
             | automatically on a CI service when the base library is
             | updated and then made available automatically through the
             | language's package repository.
             | 
             | Rust probably won't get the ability to transpile to Zig,
             | and Zig probably won't be able to transpile to Rust. Some
             | sort of Lingua Franca makes sense in a multi-language
             | world, and C (or even a subset of C) makes sense for that
             | because it already is the Lingua France, and has a very
             | small feature set to consider. I'm aware that this is a
             | controversial opinion though ;)
        
             | masklinn wrote:
             | The point of c2rust is to be a transitional tool, once the
             | system is done in Rust, compiles with Rust tooling and
             | works as it used to it's assumed it'll be much easier to
             | manage and iterate on.
        
         | ZiiS wrote:
         | I would highly value something which turned code into idiomatic
         | code; I don't care which language.
        
           | misterdata wrote:
           | Although not automatic, I find Rust's clippy to be very good
           | at suggesting improvements to code that compiles but simply
           | is not written the way it should.
        
         | smolder wrote:
         | The long tail of patterns c2rust would need to recognize to
         | reliably make _idiomatic_ code seems like a much larger
         | problem. With that as the goal, it might make sense to build a
         | separate rust-to-rust  "idiomaticizer" that can recognize
         | opportunities to reduce code complexity through refactoring,
         | and apply idiomatic patterns without changing application
         | behavior.
        
           | PudgePacket wrote:
           | Clippy already sort is is that, though it seems to target
           | smaller scope idiomatic changes.
           | 
           | It's a much harder problem for a tool to recognise the design
           | patterns C pushes you towards and refactor that to something
           | more native to Rust.
        
           | bluejekyll wrote:
           | Maybe. Though there might be lowish hanging fruit that could
           | potentially recognize arrays that could be translated to
           | slices, and heap based allocations using pointer traversal
           | that could be converted to Vec instead.
           | 
           | The real issue with doing that isn't imo, going to Rust, it's
           | understanding what still needs to be addressable in C. For
           | example, a self-contained application has no external ABI
           | dependencies, and so could assume everything that references
           | that slice must only need to be Rust. A library on the other-
           | hand might still need to present a C ABI.
        
           | harpocrates wrote:
           | As I've already posted elsewhere on this thread, such a tool
           | has been developed in parallel (and with the intent to
           | consume the output of) c2rust. Development on that occurs
           | here: https://github.com/immunant/c2rust/tree/master/c2rust-
           | refact....
        
             | smolder wrote:
             | Thanks, I hadn't seen this by the time I posted. Very cool.
        
       | floatingatoll wrote:
       | One highlight of this post is their work exposing a memory safety
       | error in the original source code:
       | 
       | > _The Rust compiler also flagged a similar but actually buggy
       | example in G_TryPushingEntity where the conditional is >, not >=.
       | The out of bounds pointer was then dereferenced after the
       | conditional, which is an actual memory safety bug._
        
         | Avamander wrote:
         | Interestingly I've too found bugs in original source similar to
         | this when rewriting in just TypeScript, so I suspect it's just
         | someone taking a look that allows the bug to be discovered.
        
       | giovannibajo1 wrote:
       | Out of curiosity, how do compilation times look, for a fresh
       | build and for the edit-compile cycle?
        
       | willvarfar wrote:
       | It would be really cool to see snippets or even the whole
       | original and transpiled code side-by-side.
       | 
       | When I was working on compilers I spent as much time making such
       | a script in a web-browser with scrolling etc as I did studying
       | the results.
        
         | ahomescu1 wrote:
         | We added the transpiled code in a new branch at
         | https://github.com/immunant/ioq3/tree/transpiled/quake3-rs and
         | also a more cleaned up refactored code base at
         | https://github.com/immunant/ioq3/tree/refactored/quake3-rs
        
         | saldivarcher wrote:
         | https://c2rust.com will show you side by side comparisons,
         | although it isn't the best looking code; in terms of
         | readability. But as mentioned in other threads, the refactoring
         | tool (https://github.com/immunant/c2rust/tree/master/c2rust-
         | refact...) aims to fix that.
        
       | bookAlot wrote:
       | Is it different or have the commands made a change to the memory
       | mapping for it to be read only at least?
        
       ___________________________________________________________________
       (page generated 2020-01-07 23:00 UTC)