Translating Quake 3 into Rust (2020)
immunant.com
immunant.com
Rust compiled binary FPS vs C code FPS.
c2rust doesn't change semantics of the C code, so there's no added safety, no extra abstraction, no checks. The converted code can be the first step in refactoring towards safe Rust, but that's a manual job.
>In a few places, the original source code contains expressions that point one past the last element of an array. Here is a simplified example of the C code:
int array[1024];
int *p;
if (p >= &array[1024]) {
}
>The C standard (see e.g. C11, Section 6.5.6) allows pointers to an element one past the end of the array.Wait? Why?
I get that char strings in C are null terminated and that might seem like an off by 1 issue if you aren’t paying attention, you still size your string one larger than your string.
What is this all about?
Lots of iterator designs have a special "end" iterator you can compare against but not deference or access - this is just the same for C arrays.
The C standard here allows pointers to elements one past the array, but it's still busted if you try to dereference it.
And it’s interesting to me that Rust doesn’t allow that considering it’s not accessing memory (yet, and that’s the whole point I’m sure.
#define COUNT(array) (sizeof(array) / sizeof((array)[0]))
int array[1024];
for (int *p = array; p < array + COUNT(array); ++p) {
// ...
}
For the loop to be well-behaved, such pointer formation must be well-defined.And the truth is that without runtime memory protection you can dereference those illegal positions.
In that way the power of the source code to teach us will still be there.
I understand if some tool that is in C and need a boost in security might use this, but giving the output code is intractable, they would still have to code in C, so this kind of defeat the some of the goals of writing code in a more secure environment.
Its important to understand that security is just one of the axis of a whole that have much more things to consider.
Having said that, maybe there will be a good use for source code in C that needs a safety boost right away in critical places, or use something like this to spot dark corners and fix the code back in C.
Also, great hacking points to whoever did this, as this is fun just because is hacking at its best.
Which one would end first and with the best version..
(Not sure if doing this from the transpiled code is the best option, giving you will miss a lot of otherwise informative context in the original source)
It seems as though the very long term plan is to divide more thoroughly the unsafe function declaration (purpose: To flag to people calling it that they need to be careful) from the unsafe block (purpose: To flag to the compiler that you checked this is OK and so it's fine that the compiler can't tell if it's OK). Today I believe the linter will optionally complain that you didn't clarify, and perhaps in the Rust 2021 edition the compiler will default to rejecting this, then perhaps Rust 2024 will just outlaw it.
I expect c2rust will eventually either just shove everything inside unsafe {} blocks as well as inside unsafe functions, or it will mark code as Rust 2018 edition and let you change that when you've written as idiomatic Rust.
Yes, so given the existence of OpenGL acceleration on chip would this rust version be significantly more performant than the c++ version?
But that's not the point. C2rust code is not "idiomatic". You get weird, unsafe Rust code full of potential side effects. The idea is to provide a means for you to start rewriting things in ways that make sense in Rust.
Would the final code be faster? Harder to tell. Maybe, maybe not. It depends on how well it's implemented, what kind of clever constructs are applied, what the game's bottlenecks are, etc.
And yet, I don't think that matters much either. Games shouldn't be bound by CPU as much nowadays unless they're doing massive simulations that are likely not language constrained. So it would be the wrong comparison to make IMO.