19

What is a situation while coding in C# where using pointers is a good or necessary option? I'm talking about unsafe pointers.

1
  • 8
    Ahhh man, I saw the question and got all happy because I would get to explain that in C# you use pointers all the time but you had to go and ruin that by explicitly saying the unsafe keyword. Dang it! :)
    – Tony
    Dec 8, 2010 at 13:12

4 Answers 4

25

From the developer of C# 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."

You may go through this for reference

1
  • "unsafe code cannot be executed in an untrusted environment." Did you mean "trusted"?
    – Don Larynx
    Apr 6, 2015 at 1:18
20

yes, there are real uses, when performance is critical and the operations are low-level

for example, i've only needed to use pointers in C# once, for image comparison. Using GetPixel on a pair of 1024x1024x32 images took 2 minutes to do the comparison (Exact match). Pinning the image memory and using pointers took less than 1 second (on the same machine of course).

4
  • 2
    I have you used LockBits for that... ( msdn.microsoft.com/en-us/library/… ) Dec 19, 2010 at 15:39
  • 1
    @configurator: this was .net 2, LockBits didn't exist Dec 19, 2010 at 18:52
  • 2
    Sure it did, it existed since 1.0... Dec 20, 2010 at 2:10
  • @configurator: my error, i got confused navigating the MSDN documentation (when i changed to .net 2 in the droplist it went to a completely different page that did not mention lockbits). Yes, that's how you pin the image memory. Dec 20, 2010 at 3:05
6

You have to remember that the designers at Microsoft are smart people and everything they add to C# has at least 1 use case. The FParsec project uses unsafe code to bring out every last drop of performance that C# is capable of. Take notice of the usage of fixed and stackalloc.

private char* ReadCharsFromStream(char* buffer, int maxCount, out string overhangChars) {
    Debug.Assert(maxCount >= 0);
    fixed (byte* byteBuffer = ByteBuffer) {
        overhangChars = null;
        try {
            while (maxCount >= MaxCharCountForOneByte) {// if maxCount < MaxCharCountForOneByte, Convert could throw
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed = false;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                buffer, maxCount, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed; // GetChars consumed bytesUsed bytes from the byte buffer
                buffer += charsUsed;
                maxCount -= charsUsed;
                if (flush && completed) return buffer;
            }
            if (maxCount == 0) return buffer;

            char* cs = stackalloc char[MaxCharCountForOneByte];
            for (;;) {
                int nBytesInByteBuffer = FillByteBuffer();
                bool flush = nBytesInByteBuffer == 0;
                int bytesUsed, charsUsed; bool completed;
                Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
                                cs, MaxCharCountForOneByte, flush,
                                out bytesUsed, out charsUsed, out completed);
                ByteBufferIndex += bytesUsed;
                if (charsUsed > 0) {
                    int i = 0;
                    do {
                        *(buffer++) = cs[i++];
                        if (--maxCount == 0) {
                            if (i < charsUsed) overhangChars = new string(cs, i, charsUsed - i);
                            return buffer;
                        }
                    } while (i < charsUsed);
                }
                if (flush && completed) return buffer;
            }
        } catch (DecoderFallbackException e) {
            e.Data.Add("Stream.Position", ByteIndex + e.Index);
            throw;
        }
    }
}
3
  • 1
    I'd say the developers (at Microsoft or any other companies) would be an idiot if they included some feature because it has 1 use case. A feature should have much more than just 1 use cases; otherwise it is a bloat.
    – Lie Ryan
    Dec 8, 2010 at 15:51
  • 4
    Raymond Chen has often said that features at Microsoft start at -100 "points". In order a feature to be implemented, it "has to have a significant net positive effect on the overall package for it to make it in". Here's ericgu's blog post about this c.2004: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx Dec 14, 2010 at 20:19
  • I'm pretty sure some String operations internally use unsafe code. So, FParsec may not have been the priority. May 17, 2016 at 15:38
4

I once had to use pointers (in the unsafe context) in a C# based windows application that would act as an interface to a headset. This application is a user interface that would allow agents (at a call center) to control their headphone settings. This application acts as an alternate to the control panel given by the headset manufacturer. Thus, their ability to control the headsets were limited when compared to the options available. I had to use pointers because I had to use the API (a Visual C++ dll) provided by the headset manufacturer using P/Invoke.

Not the answer you're looking for? Browse other questions tagged or ask your own question.