Hacker News new | past | comments | ask | show | jobs | submit login

I don't think you are correct, unless the language has changed substantially.

https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...

Among other things, you need to opt in to unsafe with the `/unsafe` compiler flag. I'm pretty much 100% certain that the `unsafe` keyword applied to scopes does not mean "treat the contained scope as if it were safe, but permit the use of unsafe operators" which is how it works in Rust.

Edit: to put some more words here, I think what you may be saying is "the unsafe fragment of C# behaves like Rust", which sounds sane to me: `unsafe` decorates regions and the compiler will complain at you if you use unsafe things outside such scopes. When I said "C#" I meant the larger language in which programs are either "safe" (verifiable) or not, and for which `unsafe { .. }` forces you into the unsafe fragment.

Rust doesn't have safe and unsafe language fragments; there is one language which follows rules similar to (as you say) unsafe C#, but which advertises itself as safe. In that language, `unsafe` moves you back in to "safe" code (or we could agree that it was never safe in the same sense that languages like C# are).




You're wrong, and that's exactly what "unsafe" block does in C# - it does not affect the outer blocks. So, for example, if you wrap your pointer arithmetic inside "unsafe", you don't need the "unsafe" modifier on the method. If you put the modifier on the method, then you don't need the modifier on the class. And the code that uses your "unsafe" classes and methods doesn't need to be in "unsafe" context.

If it were otherwise, no C# program would compile without "unsafe", because large parts of the standard library core (stuff in System) is unsafe. The only reason why "unsafe" is useful is precisely because it lets you isolate unsafe operations in a way that lets safe code invoke into them (assuming that you uphold your safety guarantees).

The /unsafe switch is a different thing - it needs to be turned out for the C# compiler to allow "unsafe" anywhere in its input, and is basically a project-level declaration that "this has some unsafe code somewhere in it".


Sure it does, Assemblies with unsafe code are tainted and fail verification.

There are deployment scenarios, like IIS, where admins can disable the execution/loading of Assemblies with unsafe code.


"unsafe" is a C# feature. Verification is a CLR feature. And they are only related in a sense that things that you can do inside "unsafe" blogs generally produce unverifiable assemblies. But the reverse is not true, you don't have to use an "unsafe" block to consume an unverifiable assembly.

Nor does "unsafe" breaks verification by itself - it's only the specific features that you might use inside (like pointer arithmetic) that would do so, and even then not all of them. For example, C# requires "unsafe" for any use of sizeof() that is not known at compile-time, and for which it needs to emit the sizeof IL opcode. So e.g. sizeof(int) is okay, but sizeof(IntPtr) is unsafe; also, sizeof all structs are considered unsafe. However, the IL opcode for sizeof is not unverifiable, and so such an assembly would pass verification, despite requiring "unsafe" in C#.


I know that, but unless one wants to become a MSIL and verification engine expert, the simplest explanation is that unsafe taints Assemblies.


Yes, but that's not what OP was talking about. Within an assembly, an unsafe block still doesn't taint any code that calls into it. And between assemblies, an unsafe assembly doesn't taint a safe one that depends on it. So it doesn't "propagate outwards".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: