3 ms·
C# has pointer goodness, in that you can do pointer arithmetic and bypass type safety. However, you have to declare an 'unsafe' context in which you'll do it.
by bunderbunder 13y ago
C# has pointer goodness, in that you can do pointer arithmetic and bypass type safety.
However, you have to declare an 'unsafe' context in which you'll do it. Unsafe contexts are tied to a local scope, which means that you can't do anything like having classes with fields of pointer types. Pointers don't outlive the function in which you use them.
Also, before you can get a pointer to an object you have to "pin" it, which tells the garbage collector not to move it around. This is necessary, of course, but it can have severe performance implications since it basically torpedoes all the garbage collector's best performance optimizations.
So pointers are there when you need them. . . but the language makes them extremely inconvenient to use them more than you absolutely need to. A pretty solid compromise, IMO.
- MichaelGG 13y agoC# can also use managed pointers (type& instead of type*). All out/ref parameters use this type of pointer, and it'll get updated by the runtime, like an object reference - no pinning necessary.
- kevingadd 13y agoInteresting, can you link to an example of their use? I've never seen them in the documentation or examples, but I remember that Managed C++ and C++/CLI have something similar. Or are you just saying that you can 'use' them via out/ref? I interpreted your post to mean that you can store them in fields, which would be stellar but seems like it would break reference lifetime guarantees.
- MichaelGG 13y agoYou only use them via out/ref. Section 13.4.2 of the CLI spec says: - Managed pointers can be passed as arguments, stored in local variables, and returned as values. - Managed pointers cannot be stored in static variables, array elements, or fields of objects or value types. So you're right, they have very limited scope as it'd be messy otherwise. It's my understanding that the JVM does not have pointers even at this level, hence Java can't do out/ref parameters. (Sure, tuples are a better way to handle many cases of out params, but sometimes a well chosen ref can really be nicer.) I think C++ also uses the term "managed pointer" but not in the same technical sense (I think it just means reference.) Using "safe" C++/CLI generation limits the scope of pointers just like we'd expect.
- kevingadd 13y agoYou can't store a raw pointer, but you can store the 'safe' forms of pointers (IntPtr, etc) which allows you to do some of the stuff you'd want to do - allocate a buffer of given size in unmanaged heap, then manipulate it entirely using struct pointers and pointer arithmetic. The key/value store I wrote in C# does this - no data lives in the managed heap, it's all sitting in unmanaged memory (mapped files, as it happens).
- MaulingMonkey 13y ago> You can't store a raw pointer You can if you mark the containing class/struct "unsafe", which allows both type safety and increased ease of use.
- kevingadd 13y agoHmmm, I've never seen this done. Thanks for the heads-up, I'll have to try it out. Are you sure you can do it with classes? I would not be shocked by being able to do it with structs.
- MaulingMonkey 13y agoSure am. using System; namespace Test2012 { unsafe class C { public byte* P; public override string ToString( ) { return new IntPtr(P).ToString( ); } } unsafe struct S { public byte* P; public override string ToString( ) { return new IntPtr(P).ToString( ); } } static class Program { static unsafe void Main( ) { fixed( byte* test = new byte[] { 1, 2, 3 } ) { var c = new C( ) { P = test }; var s = new S( ) { P = test }; Console.WriteLine( "Test: {0}", c ); Console.WriteLine( "Test: {0}", s ); } } } } Result: Test: 40510364 Test: 40510364 Press any key to continue . . .