<p>Rust has a number of memory safety features. Is it possible to extend or enhance C or C++ to also provide similar memory safety features instead of using workarounds such as the Valgrind tool suite?</p>

<c><rust><ownership><memory-safety><memory-management>
Is it possible to extend C to have the Rust concept of ownership for memory safety?
CC BY-SA 4.0
2023-06-29T05:32:37.537Z
Zig sounds something like what you are asking about -- it handles memory safety and ownership, and is interoperable with C code:  https://www.infoworld.com/article/3689648/meet-the-zig-programming-language.html
Jeremy Friesner
CC BY-SA 4.0
2023-05-16T17:44:26.373Z
In C++ `SmartPtr` and `SharedPtr` already exists which has similar semantics to rust ownership rules
mousetail 'he-him'
CC BY-SA 4.0
2023-05-16T17:45:17.880Z
C++ has been working toward this for years. Here's a talk from several years ago about their efforts: https://youtu.be/hEx5DNLWGgA
Silvio Mayolo
CC BY-SA 4.0
2023-05-16T17:46:12.523Z
@mousetail IIRC SharedPtr and SmartPtr don't have checks for not borrowing the same object as mutable more than once simultaneously.
kouta-kun
CC BY-SA 4.0
2023-05-16T17:49:31.163Z
@kouta-kun true, they do attempt to avoid use after free and memory leaks in a similar way to rust but you are correct there is no attempt to prevent aliasing
mousetail 'he-him'
CC BY-SA 4.0
2023-09-04T01:58:06.700Z
Rust got the idea from C-alike languages such as Cyclone. https://en.wikipedia.org/wiki/Cyclone_(programming_language)
Pseudonym
CC BY-SA 4.0
2024-10-11T15:44:18.250Z
Would it be fine if the program is slower and use more memory? If yes, then there would be ways to make C / C++ almost memory safe without changes to the language. For this, only the C compiler would need to be changed, so that pointers are no longer pointing directly to the memory, but are instead handles; and each memory region would be isolated from other memory regions, and use-after-free is prevented. And access to memory is always indirect and checked. But the question doesn't say if such a trade-off is OK or not.
Thomas Mueller
<p>You can add <strong>annotations</strong> to C syntax to encode and verify arbitrary properties, including ownership.</p>
<p>See <a href="https://github.com/verifast/verifast" rel="nofollow noreferrer">VeriFast</a> <a href="https://people.cs.kuleuven.be/%7Ebart.jacobs/verifast/examples/" rel="nofollow noreferrer">examples</a>, like <a href="https://people.cs.kuleuven.be/%7Ebart.jacobs/verifast/examples/chat.c.html" rel="nofollow noreferrer">this one</a> which uses multiple threads and annotations to verify there are no data races.</p>
<p>I don't think there are any examples of using VeriFast to model ownership and borrowing semantics in C, and I doubt VeriFast would be effective at doing so. However, you can certainly make a language similar to VeriFast which explicitly adds annotations to C parameters and values to define whether they are &quot;owned&quot; or &quot;borrowed&quot;.</p>
<p>The annotations don't have to be just comments either, you could define a DSL which alters C's syntax directly. You can even start replacing C syntax and changing the semantics, but at a certain point, you're basically making a new language which is no longer &quot;C&quot; (unsafe Rust looks <em>very</em> similar to C<sup>though <a href="https://www.youtube.com/watch?v=DG-VLezRkYQ" rel="nofollow noreferrer">it's not</a></sup>).</p>
<p>The problem with this approach is that once you add ownership to a language which wasn't designed with it in mind, you get issues. Because you have to annotate standard library and all external library functions with ownership, and these libraries sometimes spuriously borrow and copy data because they were not designed with ownership in mind. Among other issues.</p>
<p>I also found <a href="https://nibblestew.blogspot.com/2017/05/emulating-rust-borrow-checker-with-c.html" rel="nofollow noreferrer">this article</a> on using move-only types to emulate the Rust borrow checker in C++. So I guess adding move-only types would be the first.</p>

CC BY-SA 4.0
2023-05-16T20:22:18.807Z
2024-10-11T11:36:26.700Z
2024-10-11T11:36:26.700Z
tarzh
<p>I think this answer depends a lot on what you mean by &quot;extend C&quot; here! If you're looking for a language in which Rust ownership exists and C libraries can be used natively, that's basically what Rust already provides.  If you're imagining something like a new C compiler that gives you Rust-style errors for memory unsafe code, but still compiles existing idiomatic C without complaint, then I'm afraid that's not technically possible under a Rust-style ownership system.  This is fundamental; Rust limits the shape of representable datastructures in a way that C does not.</p>
<p>But if you're willing to accept some limits, then &quot;extending C/C++&quot; to be more Rust-like is totally possible! There are even <a href="https://www.usenix.org/legacy/event/usenix02/full_papers/jim/jim_html/" rel="noreferrer">a</a> <a href="https://ieeexplore.ieee.org/abstract/document/8543387" rel="noreferrer">few</a> <a href="https://dl.acm.org/doi/pdf/10.1145/3519939.3523443" rel="noreferrer">papers</a> showing ways to build a type system with Rust's guarantees in which idiomatic datastructures are easier to represent, or the base language remains more C-like. A lot of these papers wound up influencing the design of Rust!</p>

CC BY-SA 4.0
2023-05-16T20:07:15.463Z
2023-05-16T20:07:15.463Z
Mae Milano
<p>There is more to Rust's safety model than Ownership.</p>
<p>For Rust safety to work, it is important that the safety invariants are upheld. In safe Rust these invariants are upheld automatically. In unsafe Rust, and in non-Rust code that interacts with Rust, it is your responsibility as the programmer to uphold them.</p>
<p>An important part of Rust's safety model is that you are allowed to have sharing or mutability but normally not both at once. So if you have a reference to an object you can be confident that the object will remain in a stable state for as long as the reference is valid.</p>
<p>This is what allows, for example, you to safely derive a str from a reference to a String, or to derive a reference to one or more of a Vec's elements from a reference to the Vec. The compiler knows that as long as the reference to the String/Vec is held, not only will the String/Vec continue to exist, but that its internal buffer will remain stable.</p>
<p>Converting a raw pointer to a Rust reference is (somewhat obviously) an unsafe operation. The compiler has no idea where that pointer came from, what its lifetime will be or whether there are aliasing issues with it. Less obviously, accessing a mutable global variable is also an unsafe operation, because the compiler has no idea what other functions may be running simultaneously and trying to access said global variable.</p>
<p>Of course sometimes shared mutability is needed; Rust implements this through a concept called &quot;interior mutability&quot;. A type that implements &quot;interior mutability&quot; can be mutated through a regular (normally immutable) reference. The catch is that the type itself then becomes responsible for ensuring that sharing rules are followed regarding the interior data.</p>
<p>Another important aspect of Rust's safety model is thread safety. Rust types can declare aspects of their thread-safety through the &quot;send&quot; and &quot;sync&quot; traits, though in most cases the compiler works this out automatically from the constituent types.</p>
<p>Another important aspect of Rust's safety model is encapsulation. To do their job safely, many types need to carefully control their internal state. For example a smart pointer may be represented as a structure containing a raw pointer; the safety of the smart pointer relies on knowing that said raw pointer points to a valid combination of data and control block.</p>
<hr />
<p>Rust has pretty much all the features C has (the only exception that immediately springs to mind is variable length stack allocations). Indeed there exists at least one automatic C to Rust translation tool. I don't see any fundamental reason that the language features of Rust could not be added as extensions to C. I do however see a number of practical difficulties.</p>
<ol>
<li>How do you distinguish &quot;safe&quot; code from &quot;unsafe&quot;? If existing code has to keep compiling then &quot;unsafe&quot; has to be the default but that kind of goes against the idea that unsafe code should be the exception not the rule. Rust also distinguishes between functions that perform unsafe operations internally, but are (supposed to be) safe to call and functions that expose an unsafe interface. How will this distinction work in your language?</li>
<li>If you are extending C++, then ditto for types. This is less of an issue for C because C types are all plain old data with no encapsulation in the first place.</li>
<li>How will encapsulation work? Rust has a modules/crates system for this; will you copy that in your new language, or design something new? I don't think the C++ system of header files and manual linking is good from a safety point of view.</li>
<li>The safety model falls apart if its preconditions are violated, so to get the maximum benefit large chunks of code should be rewritten in a safe way, with calls between safe and unsafe code carefully audited to ensure that they do not violate the safety model.</li>
<li>A safe standard library is needed for safe code to use. This will parallel large parts of the C standard library. How do you avoid/manage the name conflicts this will cause?</li>
<li>How will arrays work in your language? In C/C++ arrays are not indexed directly; instead an array &quot;decays&quot; to a raw pointer, and array indexing is a shortcut for pointer arithmetic. That obviously isn't acceptable in a safe programming environment; how will you replace it while maintaining compatibility? Will arrays behave differently depending on whether you are currently in &quot;safe&quot; or &quot;unsafe&quot; code?</li>
</ol>
<p>My feeling is that by the time you have addressed all these issues, your language will effectively be &quot;two languages in a trenchcoat&quot;, sharing basic syntax but little else.</p>

CC BY-SA 4.0
2023-09-02T22:03:57.263Z
2024-10-11T11:37:01.490Z
2024-10-11T11:37:01.490Z
Peter Green
# Is it possible to extend C to have the Rust concept of ownership for memory safety?
Posted by: username_0 on 2023-05-16
Rust has a number of memory safety features. Is it possible to extend or enhance C or C++ to also provide similar memory safety features instead of using workarounds such as the Valgrind tool suite?
**Tags:** c rust ownership memory-safety memory-management
> **Comments:**
> **username_2**: In C++ `SmartPtr` and `SharedPtr` already exists which has similar semantics to rust ownership rules  
> **username_3**: C++ has been working toward this for years. Here's a talk from several years ago about their efforts: https://youtu.be/hEx5DNLWGgA  
> **username_4**: @mousetail IIRC SharedPtr and SmartPtr don't have checks for not borrowing the same object as mutable more than once simultaneously.  
> **username_2**: @kouta-kun true, they do attempt to avoid use after free and memory leaks in a similar way to rust but you are correct there is no attempt to prevent aliasing  
> **username_1**: Zig sounds something like what you are asking about -- it handles memory safety and ownership, and is interoperable with C code:  https://www.infoworld.com/article/3689648/meet-the-zig-programming-language.html  
> **username_5**: Rust got the idea from C-alike languages such as Cyclone. https://en.wikipedia.org/wiki/Cyclone_(programming_language)  
> **username_6**: Would it be fine if the program is slower and use more memory? If yes, then there would be ways to make C / C++ almost memory safe without changes to the language. For this, only the C compiler would need to be changed, so that pointers are no longer pointing directly to the memory, but are instead handles; and each memory region would be isolated from other memory regions, and use-after-free is prevented. And access to memory is always indirect and checked. But the question doesn't say if such a trade-off is OK or not.  
---
## 3 answers
### Answer by username_8 on 2023-05-16. Score: 16
I think this answer depends a lot on what you mean by "extend C" here! If you're looking for a language in which Rust ownership exists and C libraries can be used natively, that's basically what Rust already provides. If you're imagining something like a new C compiler that gives you Rust-style errors for memory unsafe code, but still compiles existing idiomatic C without complaint, then I'm afraid that's not technically possible under a Rust-style ownership system. This is fundamental; Rust limits the shape of representable datastructures in a way that C does not.

But if you're willing to accept some limits, then "extending C/C++" to be more Rust-like is totally possible! There are even [a](https://www.usenix.org/legacy/event/usenix02/full_papers/jim/jim_html/) [few](https://ieeexplore.ieee.org/abstract/document/8543387) [papers](https://dl.acm.org/doi/pdf/10.1145/3519939.3523443) showing ways to build a type system with Rust's guarantees in which idiomatic datastructures are easier to represent, or the base language remains more C-like. A lot of these papers wound up influencing the design of Rust!
---
### Answer by username_7 on 2023-05-16. Score: 11
You can add **annotations** to C syntax to encode and verify arbitrary properties, including ownership.

See [VeriFast](https://github.com/verifast/verifast) [examples](https://people.cs.kuleuven.be/%7Ebart.jacobs/verifast/examples/), like [this one](https://people.cs.kuleuven.be/%7Ebart.jacobs/verifast/examples/chat.c.html) which uses multiple threads and annotations to verify there are no data races.

I don't think there are any examples of using VeriFast to model ownership and borrowing semantics in C, and I doubt VeriFast would be effective at doing so. However, you can certainly make a language similar to VeriFast which explicitly adds annotations to C parameters and values to define whether they are "owned" or "borrowed".

The annotations don't have to be just comments either, you could define a DSL which alters C's syntax directly. You can even start replacing C syntax and changing the semantics, but at a certain point, you're basically making a new language which is no longer "C" (unsafe Rust looks *very* similar to Cthough [it's not](https://www.youtube.com/watch?v=DG-VLezRkYQ)).

The problem with this approach is that once you add ownership to a language which wasn't designed with it in mind, you get issues. Because you have to annotate standard library and all external library functions with ownership, and these libraries sometimes spuriously borrow and copy data because they were not designed with ownership in mind. Among other issues.

I also found [this article](https://nibblestew.blogspot.com/2017/05/emulating-rust-borrow-checker-with-c.html) on using move-only types to emulate the Rust borrow checker in C++. So I guess adding move-only types would be the first.
---
### Answer by username_9 on 2023-09-02. Score: 5
There is more to Rust's safety model than Ownership.

For Rust safety to work, it is important that the safety invariants are upheld. In safe Rust these invariants are upheld automatically. In unsafe Rust, and in non-Rust code that interacts with Rust, it is your responsibility as the programmer to uphold them.

An important part of Rust's safety model is that you are allowed to have sharing or mutability but normally not both at once. So if you have a reference to an object you can be confident that the object will remain in a stable state for as long as the reference is valid.

This is what allows, for example, you to safely derive a str from a reference to a String, or to derive a reference to one or more of a Vec's elements from a reference to the Vec. The compiler knows that as long as the reference to the String/Vec is held, not only will the String/Vec continue to exist, but that its internal buffer will remain stable.

Converting a raw pointer to a Rust reference is (somewhat obviously) an unsafe operation. The compiler has no idea where that pointer came from, what its lifetime will be or whether there are aliasing issues with it. Less obviously, accessing a mutable global variable is also an unsafe operation, because the compiler has no idea what other functions may be running simultaneously and trying to access said global variable.

Of course sometimes shared mutability is needed; Rust implements this through a concept called "interior mutability". A type that implements "interior mutability" can be mutated through a regular (normally immutable) reference. The catch is that the type itself then becomes responsible for ensuring that sharing rules are followed regarding the interior data.

Another important aspect of Rust's safety model is thread safety. Rust types can declare aspects of their thread-safety through the "send" and "sync" traits, though in most cases the compiler works this out automatically from the constituent types.

Another important aspect of Rust's safety model is encapsulation. To do their job safely, many types need to carefully control their internal state. For example a smart pointer may be represented as a structure containing a raw pointer; the safety of the smart pointer relies on knowing that said raw pointer points to a valid combination of data and control block.

---

Rust has pretty much all the features C has (the only exception that immediately springs to mind is variable length stack allocations). Indeed there exists at least one automatic C to Rust translation tool. I don't see any fundamental reason that the language features of Rust could not be added as extensions to C. I do however see a number of practical difficulties.

1. How do you distinguish "safe" code from "unsafe"? If existing code has to keep compiling then "unsafe" has to be the default but that kind of goes against the idea that unsafe code should be the exception not the rule. Rust also distinguishes between functions that perform unsafe operations internally, but are (supposed to be) safe to call and functions that expose an unsafe interface. How will this distinction work in your language?
2. If you are extending C++, then ditto for types. This is less of an issue for C because C types are all plain old data with no encapsulation in the first place.
3. How will encapsulation work? Rust has a modules/crates system for this; will you copy that in your new language, or design something new? I don't think the C++ system of header files and manual linking is good from a safety point of view.
4. The safety model falls apart if its preconditions are violated, so to get the maximum benefit large chunks of code should be rewritten in a safe way, with calls between safe and unsafe code carefully audited to ensure that they do not violate the safety model.
5. A safe standard library is needed for safe code to use. This will parallel large parts of the C standard library. How do you avoid/manage the name conflicts this will cause?
6. How will arrays work in your language? In C/C++ arrays are not indexed directly; instead an array "decays" to a raw pointer, and array indexing is a shortcut for pointer arithmetic. That obviously isn't acceptable in a safe programming environment; how will you replace it while maintaining compatibility? Will arrays behave differently depending on whether you are currently in "safe" or "unsafe" code?

My feeling is that by the time you have addressed all these issues, your language will effectively be "two languages in a trenchcoat", sharing basic syntax but little else.
---
