Comment by SideburnsOfDoom
1 day ago
> The unsafe keyword is being redesigned
OK, I see a lot of C# code often and over a long time.
I see the "unsafe" keyword used approximately never.
I'm sure that this is useful for some cases. But not everyday things for most of us. If we did use it, it would be carefully isolated in a library for a specific purpose.
This moves C# to a more modern systematic understanding of what this keyword is for, but it'll remain very rare in C# the same way it's rare in Rust, and presumably in Swift.
The choice of keyword "unsafe" is partly psychological. Turns out if you called this exact same feature "trusted" or whatever the programmers don't have the appropriate feelings about it. They want to write trusted code, they don't want to write unsafe code, so making them write the keyword "unsafe" provides that psychological disincentive.
Initialize liveHandgrenade;
There are standard library APIs that let you do memory-unsafe things without the unsafe keyword (CollectionsMarshal, MemoryMarshal). They're useful, but the burden is on the caller to uphold the invariants. This proposal seems aimed at making that kind of contract more explicit and obvious.
Many of us use it in scenarios where others would write a blog post about a rewrite in Rust, C++ or whatever.
CLR was designed to support languages like C++, yet many don't learn the knobs.
Any lesser known knobs one should know? I'm considering a .NET backend for my compiler
If on Windows, one is to see what C++/CLI would generate, with ildisam or similar tool.
You can also emit MSIL for what you actually want to do, with low-level bytecodes.
Then there is unsafe, ref structs, stack allocation, fixed buffers, scoped types, manual memory management, array pools, memory pipelines, the various span variants.
> I see the "unsafe" keyword used approximately never.
The core libraries of .NET are written in C# and it's like a completely different language:
https://github.com/dotnet/runtime/blob/main/src/libraries/Sy...
One might not make use of it application code but these features a major part of the platform itself.
Good language has a unique flavor, and better language allows for diverse tastes and usages
Around here C# is only really used at stagnant middle sized companies with horrible code bases. The sort where the company follow Uncle Bob religiously, while completely misunderstanding everything Uncle Bob ever said. Doesn't mean the language (and it's runtime) can't be good.
The examples in Clean Code show that Uncle Bob himself misunderstood heuristics as strict rules that are to be taken to the extreme. There's nothing to not misunderstand.
Yes, many people instinctively stay away from anything microsoft (except github, typescript and npm). But the stack is solid. I’m always reminded of Stack Overflow and how they built on asp.net and like 7 servers and it scaled very well for years.
Everyone has what they like and what they’re familiar with, and for better or worse, especially for startups it’s rarely .net. But I couldn’t imagine e.g. using js instead on the back end, but that’s just me.
A VM with good FFI and structs is pretty unique and all of the tooling around .NET is excellent
F# is a sleeping giant of capability in the FP/ML space, being able to use a lot of the existing tooling
People rightfully point out how it's sort of second class in comparison to C# at times, but its still A tier tooling that few languages have
In a game development context, especially where C++ interop is involved and a lot of code lives across a boundary where memory is owned by C++ but you want to avoid/minimize marshaling overhead or just generally maximize performance, the unsafe keyword is quite handy, but outside of those you can indeed probably get around by approximately never using it.
There's a lot of power C# gives you if carefully curated, making a lot of cases where people previously might have seen C++ as the only option as suddenly quite viable.
... See also the somewhat arcane Unsafe.As etc APIs
Yes, the article itself even points out that the C# default has always been to make the unsafe keyword a compile error by default and must be opted in at the project level to even use it. So most C# application code doesn't use unsafe.
The benefits here are mostly to specific types of libraries, often either deeply performance-focused libraries or complex native interop libraries (things that wrap C/C++/Rust/etc code as a .NET Library).
The article mostly also points out that like Span<T> many of the biggest benefits to application writers here are going to be making the runtime itself quietly better (faster and safer). The new compile errors will make Base Class Library code and runtime code more auditable for potential memory safety issues by bubbling up safety concerns higher into the code stack and making the boundaries between the unsafe and "safe" code much easier to find. It will provide additional incentive to narrow the number of things that need to be marked `unsafe` and provide extra incentive to the runtime to minimize `unsafe` dependencies. This includes adding additional weight furthering the push for rewrites from "performance" C++ code (under the hood of the runtime) to memory safe C# code with modern safety/performance tools like Span<T>, while also reducing some of the similar pressure to rewrite that C++ code as Rust for memory safety reasons rather than directly to C# (with less overhead of transitioning to/from "managed code" and "native code") by providing similar `unsafe` safety marker tools to what Rust has had since 2024.
(ETA: There may still be some possible breaking changes to today's application code when opting into the new safety checks though by adding possibly more uses of the unsafe keyword than were needed before as many APIs with unsafe in the name or documentation such as the Marshall.* family of functions will probably get new safety documentation. Most of those concerns are still in P/Invoke and native library interop spaces and would probably be refactored into libraries to re-isolate the unsafe code and have the application continue to not allow unsafe blocks, but that will be tech debt migrations that may show up when opting into the new behaviors.)
C# is like Rust in the sense that a regular (web, desktop, etc.) developer probably won’t need unsafe, but it’s useful for lower-level work in libraries and CLI tools, especially where performance is important.