Live data from Hacker News

Rust to C compiler – 95.9% test pass rate, odd platforms

fractalfir.github.io

41–50 of 264 posts

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#41
post #9

Earlier quoted context omitted.

> 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.

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.

They are discussing C to Rust, not the topic of the post. Rust would need to guess the semantics of the original C.

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#42
post #33
post #7

Lots of interesting use cases for this. First one that comes to mind is better interop with other languages, like Python.

What does this gain you that you can't already do with `extern "c"` functions from rust?

’Extern c’ still uses Rust. You want to skip Rust and call C from other languages directly.

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#43
post #34

At first I read it as C to rust compiler. What is the point of compiling rust to C?

> What is the point of compiling rust to C? To address platforms that don't support Rust. TFA mentions NonStop, whatever it is.

Fault-Tolerant mainframe type systems.

https://en.m.wikipedia.org/wiki/NonStop_(server_computers)

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#44
post #42
post #33

Earlier quoted context omitted.

What does this gain you that you can't already do with `extern "c"` functions from rust?

’Extern c’ still uses Rust. You want to skip Rust and call C from other languages directly.

Not GP, but what is the point of touching Rust at all then?

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#45
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 ...

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#46
post #36
post #34

At first I read it as C to rust compiler. What is the point of compiling rust to C?

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.

Exactly. Btw rust toolchain is quite complicated while a code that was tanspiled to C might be as well compiled to e.g. 6052

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#47

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 __bu…

thank for PR. very fast turn around.

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#48

But does it carry the Rusty guarantees?

Why wouldn't it?

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.

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#49
post #27
post #25

Earlier quoted context omitted.

How does the rust compiler assure that when compiling to machine code? Machine code is less safe than C after all.

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.

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.

Re: Rust to C compiler – 95.9% test pass rate, odd platforms

#50

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 __bu…

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!

Post reply on HN