If the concern is memory safety, I'd invite comparison with migration to the scpptool-enforced memory-safe subset of C++ [1]. If your C++ code is "idiomatic modern" C++, then the changes required to conform to the safe subset (in an idiomatic way) are often modest, and as demonstrated in the link, often something an LLM can handle for you. Since the safe subset does not impose a universal restriction on mutable aliasing the way Rust does, it doesn't require wrapping everything in `RefCell<>`s or anything like that (unless the objects in question are being shared between threads).
If your C++ code is more "legacy" than "modern", the migration is generally still straightforward, but will often involve additional run-time overhead, like it does with this cpp2rust, but to a lesser degree I think. Objects allocated on the stack can (safely) remain allocated on the stack even when they are the target of pointers. And still, no `RefCell<>` equivalents are required for objects that aren't shared between threads.
If I can autoport my C++ to Rust, and the port is confirmed identical, and the Rust is confirmed safe, can't I use that to reason about the safety of my C++? Is safe C++ just a matter of proving it has a safe Rust equivalent?
It depends on what “confirmed identical” means. Most compilers (or translators as you like) only guarantee that the output program represents a subset of the behaviors of the input program so it could be that subset is the “safe as in Rust” subset.
GP is referring to the article's title, as in "safe Rust", as in "Rust with no unsafe keyword", as in whether it has undefined behavior or not.
Granted the premise is rather brittle, since all Cpp2Rust does is to convert UB to runtime crashes, which can be undecidable, and cannot be used to prove anything about the original C++ code.
Interesting, but unpractical. As I know there is no way to perform automatic translation from one programming language to another without producing code which looks terrible in the destination language.
In this particular example I see no real safety benefits. If the source program is buggy, the result translated program willcrash at runtime, but if it's (mostly) bug-free and UB-free, such translation gives no benefits.
> our reference-counted translation model, where every variable is pessimistically wrapped inside a Rc<RefCell<T>> type, checks that would usually execute at compile-time are shifted to run time, degrading performance.
> Notable unsupported constructs include: union, volatile, goto, exceptions, bitfields, placement new, user-defined copy/move constructors, dynamic_cast, const_cast, base classes with fields or non-virtual methods, multiple inheritance, and multi-threaded code.
So, most C++ code I have seen in my forty years of coding.
Lol, “user defined copy/move constructors” That’s actually so many types that would define this
Base classes with fields or non-virtual methods are not exactly rare neither.
From the point of view of C++26, which is already ratified, and half implemented in GCC 16, I think your list should even be longer.
The readme is rather slim on C++ versions.
If the concern is memory safety, I'd invite comparison with migration to the scpptool-enforced memory-safe subset of C++ [1]. If your C++ code is "idiomatic modern" C++, then the changes required to conform to the safe subset (in an idiomatic way) are often modest, and as demonstrated in the link, often something an LLM can handle for you. Since the safe subset does not impose a universal restriction on mutable aliasing the way Rust does, it doesn't require wrapping everything in `RefCell<>`s or anything like that (unless the objects in question are being shared between threads).
If your C++ code is more "legacy" than "modern", the migration is generally still straightforward, but will often involve additional run-time overhead, like it does with this cpp2rust, but to a lesser degree I think. Objects allocated on the stack can (safely) remain allocated on the stack even when they are the target of pointers. And still, no `RefCell<>` equivalents are required for objects that aren't shared between threads.
[1] https://github.com/duneroadrunner/scpptool/blob/master/READM...
If I can autoport my C++ to Rust, and the port is confirmed identical, and the Rust is confirmed safe, can't I use that to reason about the safety of my C++? Is safe C++ just a matter of proving it has a safe Rust equivalent?
It depends on what “confirmed identical” means. Most compilers (or translators as you like) only guarantee that the output program represents a subset of the behaviors of the input program so it could be that subset is the “safe as in Rust” subset.
> the Rust is confirmed safe
keep in mind that rust:
- does not prevent logic errors
- does not prevent stack overflows
- does not prevent out of memory errors
- does not prevent bitflips caused by faulty hardware or cosmic rays
- does not prevent memory leaks
- does not prevent unrecoverable errors (panics)
- does not prevent memory safety related issues in an unsafe context
GP is referring to the article's title, as in "safe Rust", as in "Rust with no unsafe keyword", as in whether it has undefined behavior or not.
Granted the premise is rather brittle, since all Cpp2Rust does is to convert UB to runtime crashes, which can be undecidable, and cannot be used to prove anything about the original C++ code.
The conversions seem to use (sometimes?) unsafe blocks.
Interesting, but unpractical. As I know there is no way to perform automatic translation from one programming language to another without producing code which looks terrible in the destination language.
In this particular example I see no real safety benefits. If the source program is buggy, the result translated program willcrash at runtime, but if it's (mostly) bug-free and UB-free, such translation gives no benefits.
Why does the example not show an example of unsafe C++?
The Readme is slim, with the intent to show a hello world but the tests do. Look in https://github.com/Cpp2Rust/cpp2rust/blob/master/tests/ub/
This was featured at PLDI 26 [1].
I'm not yet convinced that the issue of C's unsafety is better solved by translating it to Rust rather than using Fil-C [2].
https://pldi26.sigplan.org/program/program-pldi-2026/
https://fil-c.org/
The original paper quoth:
> our reference-counted translation model, where every variable is pessimistically wrapped inside a Rc<RefCell<T>> type, checks that would usually execute at compile-time are shifted to run time, degrading performance.
Yeah the readme definitely needs some non-trivial examples. How does this handle raw pointers? Operator overloading? Inheritance?
Why didn't they target Zig?
[flagged]
codex "/goal port this codebase from c++ to rust"
alternatively (single files only, though): https://claude.ai/public/artifacts/66739932-5e3f-45b6-adaa-9...