Hacker News new | ask | show | jobs
by brighteyes 2528 days ago
It's interesting that someone in Microsoft is talking about Rust, but the article is very flawed. For example,

> C#, a programming language developed by Microsoft, also features some memory access improvements but is not as advanced as Rust. [..] Besides [Rust] being superior to C# in regards to better memory protections

That's false, isn't it? C# is a memory safe language, period. It relies on GC for that.

In fact C# has arguably better memory safety than Rust because you can do things safely in C# that you would be forced to use 'unsafe' in Rust for. (Granted, then you have overhead from GC, but that's not what the author is talking about.)

> Rust is also more popular with developers these days and might be easier to recruit for.

The author has misinterpreted what "most loved" means in the quoted survey: it means that among Rust developers, it gets a very high rating. That says nothing about how big that group is, nor how popular it is in the general population of developers.

The Rust community is growing but still very small - it's an emerging language. Almost everyone that uses it decided to use it because they like it. (That doesn't diminish the accomplishment - there are other emerging languages that are not as loved by their users.)

13 comments

The article is most flawed because Microsoft has been using Rust for a long time already.

The MSRC article says:

>in a new blog series we will highlight Microsoft’s exploration of safer system programming languages, starting with Rust

so it appears the zdnet author misinterpreted this to mean it hasn't started using it yet.

As an example, https://github.com/Azure/iotedge had its first Rust code checked in in February 2018.

MS has also already been contributing to Rust and LLVM to get it working on Windows ARM32 and ARM64.

Publishers will try to squeeze every click possible out of minor topics when they run out of ideas. Like when Microsoft anounced project Athens for Go last year: https://hub.packtpub.com/microsoft-announces-project-athens-...
Lol, yes this is ZDnet.

There are several azure services running at least some Rust and job descriptions for IOT stuff have mentioned it for months.

> C# is a memory safe language, period

It's quite possible that what the author intends by “memory protections” is broader than what is captured by “memory safety”; e.g., the borrower checker is, in a sense, a way of protecting memory from unexpected changes in parallel tasks.

I think that's too generous to the author given the other mistakes in the article, but sure, if you expand the meaning beyond regular memory safety, then it becomes a mixed picture: Rust protects from some race conditions, but other types of parallel code must use 'unsafe'. And as mentioned before some data structures can be done safely in C# but not in Rust.

It is definitely false for the author to say Rust is "superior to C# in regards to better memory protections", in any definition of "memory protections".

Is the author's purported "wording" in the article from extensive coding experience in rust and c#, or any other language?

Or, did someone prod a journalist with little familiarity in programming theory, to write positive "spin" on Rust being explored by Microsoft? Is it even news for the world's largest software company (by market cap), to explore the use of emerging languages?

> the author's purported "wording"

I missed the part where whether the author used words and, if so, which words they were was a matter of controversy.

> “memory protections” is broader ...

That's the part you cited, and went on to imply the author might be referring to Rust's borrower checker. Nothing from the author's "wording" implies knowledge of Rust's memory protection techniques

> That's false, isn't it? C# is a memory safe language, period. It relies on GC for that.

The original post's whole sentence there is basically nonsense. They're different enough that it's hard to call either one more advanced or having better memory protection at all.

Using just plain C#, it has better memory protection, since the GC and runtime make it impossible to leak, double-free, or access out-of-bounds. But there's a higher cost for that, and the system for managing non-memory resources is not as reliable - you can leak file handles, network handles, etc more easily. Not up on the latest in Rust, but I think it's possible to leak memory if you are sufficiently clever and doing really weird stuff. But the standard ownership model is great at making it really hard to leak or mismanage any resource, not just memory.

It's hard to call either one more advanced either. .NET has a massive std lib and C# has been getting some cool new features. It's still a runtime language though, with the limitations that come from that. Rust's lifetime and ownership system is pretty advanced, but wouldn't make sense for a runtime language.

> the GC and runtime make it impossible to leak, double-free, or access out-of-bounds

This is false.

Neither C# nor Rust protect from memory leaks. There are actually some gotchas in C# that can cause memory leaks - for example, you have to be very careful about events. Memory leaks are not memory unsafe, though.

On the topic of actual memory safety - C# has unsafe blocks just like Rust does. Safe Rust is just as safe from memory safety problems as safe C#, even more so, because C# doesn't require unsafe for FFI, where all bets are off. And unsafe C# is just as unsafe as unsafe Rust can be.

Yes, leaks are possible in all languages.

In Rust you can leak due to reference cycles for example: https://doc.rust-lang.org/book/ch15-06-reference-cycles.html

C# will clean up reference cycles, but an unintended reference can cause leaks (if you forget to remove it).

In both languages such leaks are not good, but at least they aren't memory safety issues.

> you have to be very careful about events

The only gotcha that can cause memory leaks in C# is a GC root, i.e. referencing something on a stack, that is static or that is pinned. Events/delegates are not special in any way, they are simply a reference footgun because it's non-obvious that they contain a reference to the object that contains the handler.

> I think it's possible to leak memory if you are sufficiently clever and doing really weird stuff

Note that Rust provides an easy way to intentionally leak memory, unlike many other languages: https://doc.rust-lang.org/std/mem/fn.forget.html

`mem::forget()` only prevents destructors from running, which leaks data managed by the destructor as a side effect, but it gives no guarantees about not freeing the object passed to it (e.g. if you call it on a stack-allocated object, it can't leak it).

`Box::leak()` leaks memory.

> That's false, isn't it? C# is a memory safe language, period. It relies on GC for that.

True. I think they are conflating memory-safety and thread-safety here. Rust definitely offers better thread-safety properties. This is somewhat nice, since in my experience thread-safety issues are the more commonly undetected bugs - which are later on tricky to find and might require big refactoring efforts to fix. They are also often the source of the memory-unsafety issues.

Imho Go currently has the best blend of both properties for a GCed language - since the race detector does a good job of detecting thread-safety issues. I wish for Java and C# to get the same.

Rust protects from data races. AFAIK C# will not tell you where you need to put mutexes.
Yes, it's quite possible to cause tearing in C#. It does not cause undefined behavior, but it can, for example, break invariants (supposedly enforced by privacy) in large enough structs.

See this example where I break encapsulation in a struct by abusing a race condition:

https://github.com/VictorGavrish/MultiThreading/blob/master/...

> That's false, isn't it? C# is a memory safe language, period. It relies on GC for that.

Ah, that is also false. A GC makes a language safer, but it does not protect against race conditions, so it is not entirely memory safe.

Of course, many languages that are referred to as memory safe have this loophole, but that may also be due to there not previously being a concurrent language with suitable protection in this area.

I think people refer to memory safe in general as "not being able to override memory that is not currently owned by a referred object in the program" - which certainly applies to all GCed languages.

It's definitely true that this does not imply thread-safe, and the ability to prevent the mess up the consistency of valid objects.

> I think people refer to memory safe in general as "not being able to override memory that is not currently owned by a referred object in the program" - which certainly applies to all GCed languages.

This is absolutely false. Race conditions in native structures can very easily invalidate any memory safety guarantees provided by the language, causing issues such as buffer overflows.

In other words, the presence of any memory unsafe operation leads to a total and immediate loss of all memory safety.

See for example how races in Go can lead to type confusion for interface types (fat pointers) through store tearing (non-atomic writes): https://research.swtch.com/gorace or https://groups.google.com/forum/#!msg/golang-dev/mXjFejQ5A3Q...

The former has a detailed explanation, the latter has a code example that shows more clearly what the technique can be used to do (cast a struct A to unrelated struct B with different length, thus allowing out-of-bounds reads/writes).

If on the other hand you were just saying that these languages are just called memory safe, even though they aren't, then yes. That's what I said.

Yeah; the original post from Microsoft was linked yesterday and this just seems like a dodgy regurgitation of it.
You could make a coherent argument that Rust has better memory protections than C#. For instance data races are protected, that is a memory protection. Arguably replacing null with options is a form of better memory protection as well.
> you can do things safely in C# that you would be forced to use 'unsafe' in Rust for

Could you provide an example? I thought pretty much everything could be achieved, albeit sub-optimally with reference counting (data structures).

call c api functions that take pointers.
You would need to do this unsafely in C# though which is kind out of bounds of the discussion/my point.
You can't write a doubly-linked list without unsafe in Rust.
Could not find any unsafe usage in Ian Jackson's, and it depends on no other crates.

https://lib.rs/crates/rc-dlist-deque

OK, perhaps we should say a doubly-linked list where each node contains the data and two pointers. While this is safe, it's also fairly inefficient, storing an extra counter with every node, which are dynamically updated, just to keep the borrow checker happy.
The word you're looking for is "intrusive".
Nope, intrusive is different. Because this is using an Rc (reference counted pointer) for the forward and backward pointers, these counters are both set to '2', as (almost) everything in a doubly-linked list has two things pointing to it, the thing after and the thing before.
That's not true and a misunderstanding of what `unsafe` does. It has nothing to do with borrow checking (which is what trips people up when writing a double linked list). Unsafe is primarily used for FFI and lets you dereference raw pointers (among a few other related uses).
It is in general an escape hatch for being able to write code that isn't possible in safe Rust. Limitations of the borrow checker (e.g. for backpointers in circular data structures) definitely fall into that category. Even without FFI Rust would not be practical without unsafe.
You would use raw pointers instead of normal ones the type system (including borrow checker) cares more about, so ultimately yes it is about subverting the type system.
C# is a typo. If you read the original post it always refers to C++ when discussing memory safety.
This is getting semantically thorny, but I would not interpret memory protections as memory safety. The borrow checker just makes it easier to establish bounds on data flow, for which there are a number of benefits beyond preventing use-after-free and unintended aliasing.
I think by "memory access improvements" they are referring to the new zero cost memory abstractions (called Span and Memory) not to memory safety. This makes the most sense in context because these abstractions were inspired by similar zero cost abstractions in rust.

https://msdn.microsoft.com/en-us/magazine/mt814808.aspx

https://docs.microsoft.com/en-us/dotnet/api/system.span-1?vi...

The lack of explanation of why the author thinks Rust is better than C# makes me think the author is a troll.
Why would you decide someone is maliciously trolling the internet by writing an article on tust versus the far far more likely situation of the author and/or target readership being unfamiliar with the domain leading to poor quality content being churned out to hit a deadline?
Critical thinking is recognizing when people throw out statements without presenting any evidence. If you fill an your article with accusations and without evidence then your trolling.