Should you use pointers (unsafe code) in C#?

20,707

Solution 1

From "The Man" himself:

The use of pointers is rarely required in C#, but there are some situations that require them. As examples, using an unsafe context to allow pointers is warranted by the following cases:

  • Dealing with existing structures on disk
  • Advanced COM or Platform Invoke scenarios that involve structures with pointers in them
  • Performance-critical code

The use of unsafe context in other situations is discouraged.

Specifically, an unsafe context should not be used to attempt to write C code in C#.

Caution:

Code written using an unsafe context cannot be verified to be safe, so it will be executed only when the code is fully trusted. In other words, unsafe code cannot be executed in an untrusted environment. For example, you cannot run unsafe code directly from the Internet.

Reference

Solution 2

If you have to.

Say that you need to false color a large grayscale image, say 2000x2000 pixels. First write the 'safe' version using GetPixel() and SetPixel(). If that works, great, move on. if that proves to be too slow, you may need to get at the actual bits that make up the image (forget about Color matrices for the sake of the example). There is nothing 'bad' about using unsafe code, but it adds complexity to the project and should thus be used only when necessary.

Solution 3

I can't remember ever having to do so - but I haven't done much interop. That's the most common application, I believe: calling into native code. There are a very few times where using pointers allows you to optimise some code, but it's pretty rare in my experience.

If it's any guide, I consider myself to be pretty experienced in C# but if I had to do any unsafe code I'd have to consult the spec/books/MSDN to guide me. Of course there will be plenty of people who are happy with unsafe code but less familiar with (say) query expressions...

Solution 4

I would say the main issues are:-

  • Unsafe code is not verifiable. This means that the code can only be ran by a user from an entirely trusted context, thus if you ever need a user to run the code from anywhere less than entirely trusted (e.g. a network share not configured to be so), you're screwed.
  • Lack of verifiability (hm not sure if that's actually a word) also means you could potentially mess up memory in your program. You are potentially bringing whole classes of bugs back into your application - buffer overruns, dangling pointers, yada yada yuck yuck. not to mention being potentially able to corrupt data structures in memory without realising when your pointer goes weird.
  • If you want your unsafe code to access managed objects you need to 'pin' them. This means the GC is not allowed to move your object around in memory and thus the managed heap can become fragmented. This has performance implications; therefore it's always important to determine whether any potential perf gain isn't outweighed by this issue.
  • Your code becomes harder to understand for programmers not used to the unmanaged approach. They may then be more liable to shoot their foot off with some of the 'freedom' unsafe code gives them.
  • You become able to write un-type-safe code; this really rather eliminates a lot of the advantage of a nice warm fuzzy managed language. Now you can encounter horrible type safety issues. Why take that step backwards?
  • It makes your code uglier.

I'm sure there's more that could be added to the list; in general, as others' have said - avoid unless you have to.e.g. calling an unmanaged method via p/invoke which requires some special pointer funking. Even then the marshaller will mostly prevent the need for it, mostly.

'The man' also say avoid unless necessary, basically.

Oh, nice article about pinning here on MSDN by the way.

Solution 5

Unsafe code is a fully supported function of the .NET CLR. The benefits are performance and compatibility with binary code. The runtime is a sandbox which prevents you from crashing and burning, but that comes with a cost. In situations where you are doing extremely intensive operations against large blobs in memory, for example image manipulation, it is faster to step outside the normal safety the runtime provides.

That having been said, I think most people here would say "don't do it". The vast majority of .NET developers will not run into a case in their normal activities that can only be solved by using unsafe code.

Share:
20,707

Related videos on Youtube

vishwas kumar
Author by

vishwas kumar

Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies. --Teach Yourself Programming In Ten Years

Updated on May 01, 2020

Comments

  • vishwas kumar
    vishwas kumar about 4 years

    Should you use pointers in your C# code? What are the benefits? Is it recommend by The Man (Microsoft)?

    • gsscoder
      gsscoder over 11 years
      Use of pointers is generally related to p/invoke. See this article: c-sharpcorner.com/UploadFile/pcurnow/…
    • marknuzz
      marknuzz almost 8 years
      If you're making heavy use of unsafe code for one specific use, it can help to to keep all of that code in a private inner class, contained by a public class that is safe. I don't like the idea of having the rest of the application dealing with pointers. Any obscure bugs that come up can then be traced to this pair of classes instead of an unknown place in the rest of the application. It keeps the added complexity from leaking out into the rest of the codebase.
  • Ed S.
    Ed S. about 15 years
    I do a lot of image processing and LockBits has saved me a lot of effort there. I have never used unsafe code anywhere else though.
  • Steven Behnke
    Steven Behnke about 15 years
    I've used it sometimes, but rarely even with interop. We wrapped 16 bit TWAIN and only had to use IntPtr not unsafe code. Only place I've thought of using it was for bitmap manipulation so I could pin the memory.
  • Caleb Vear
    Caleb Vear about 15 years
    The only time I have ever used it is also for image manipulation. I had to invert a specific portion of the image and doing it without unsafe code had a noticable lag, but with the unsafe code it was being done in < 1 ms.
  • Steven A. Lowe
    Steven A. Lowe about 15 years
    image processing with LockBits and some bit-level manipulation in a genetic algorithm are the only times i've ever needed it, but the performance gain was extraordinary!
  • Carra
    Carra almost 15 years
    Well, for imageprocessing the GetPixel and SetPixel methods are insanely slow. I also use it for fast bitmap editing including one genetic algorithm which would be my own version of the EvoLisa project ;) Apart from that I only remember using to call interop functions for getting all icons from an *.ico file which the .net versions did not support.
  • Dinis Cruz
    Dinis Cruz over 12 years
    remember that normally (under full trust) the verifier is disabled which means that your 'safety' really depends on the compiler to do its job correctly. Basically you can create IL that performs unsafe actions
  • osirisgothra
    osirisgothra over 10 years
    wouldn't throwing an unsafe codeblock into an otherwise safe .NET application make it LESS clean? I think you might be mistaking C/C++, many people coming from there frown on managed code a lot because they think it's slower. It was in earlier versions, but it is much faster and reliable these days than even native code, especially on linux systems where there is almost no bloat in there, in fact, my .NET apps in linux run faster than my C++ apps do..
  • Andrew Rondeau
    Andrew Rondeau almost 8 years
    Usually, when I see unsafe C# code in examples on the internet, it's a code smell. Meaning, someone tried to write C code in C#. At this point, the Managed.Interop namespace is pretty extensive, and you can wrap an IntPtr to a single-instance struct, so unsafe is really for performance-sensitive code by CLR experts. It's not a way to keep old tricks with pointers alive in the managed world.
  • TheLethalCoder
    TheLethalCoder over 7 years
    Note that dealing with images is probably the most common use in using unsafe code to give a performance boost. However, I would argue that you should use LockBits only before going to unsafe and LockBits i.e. a middle step.
  • Ed S.
    Ed S. over 7 years
    @TheLethalCoder: eh, maybe, if you don't have experience. Once you've done the work before you know whether or not it will be needed. It's not a premature optimization.
  • Daniel
    Daniel over 6 years
    I could not agree more. Consider converting an image from one platform to another, each using different classes and formats to represent images. You can either copy out an array, iterate over it to convert, then copy it into the target, or... you can use pointers to copy & convert in one pass, from source to destination. The "safe" way is grossly inefficient if you know what you are doing.