Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement C++ style function pointers in C#?, Without using delegates

I am learning pointers in C# and was curious if one can use C++ style function pointers in C#. Yes, I know C# has its own equivalent concept for Function Pointers(called as delegates). But I just want to know if the same can be achieved using pointers in C#, without using delegates.

If using pointers is completely legal in C#(using unsafe option) and pointer semantics is almost similar to C/C++ then in my opinion one should also be able to use C/C++ style function pointers as well. Please guide me on this. Is it possible? If yes how?, If not then why?

Please notice the similarity of pointer usage in C# and C/C++ as depicted in below example

/* Using pointers in C# (Very similar to C/C++) */
using System;

namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe static void Main()
      {
         int[]  list = {10, 100, 200};
         fixed(int *ptr = list)

         /* let us have array address in pointer */
         for ( int i = 0; i < 3; i++)
         {
            Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
            Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
         }

         Console.ReadKey();
      }
   }
}
like image 922
Shashikant Mitkari Avatar asked Apr 11 '16 20:04

Shashikant Mitkari


4 Answers

The other answers which note that C# has no built-in support whatsoever for function pointers, even in unsafe mode, are correct.

It is interesting to consider what it would take to implement this feature. As it happens, I have implemented this feature in an unreleased prototype version of C# back in... 2010? Around then. Maybe 2011.

We decided upon review of the prototype that the syntax was insufficiently pleasant and the usage cases were insufficiently compelling to justify going forward with the feature.

First off, what is the compelling benefit of the feature over delegates? Delegates are typesafe and nicely capture the semantics of a reference to a function bound to its receiver. However, in some "systems" scenarios -- the same scenarios in which you would be using raw pointers to memory in the first place -- delegates are simply too heavyweight. They are garbage collected, they increase collection pressure, they're a large object compared to the size of a pointer, they have costs on every invocation, and so on. Or, you might be constructing your own custom layout vtables to interoperate with some particularly nasty bit of unmanaged code, and you wish to invoke a function pointer that you've just put down in your vtable. And so on.

The CLR has the necessary instruction:calli, a pointer-indirected call. But there is no syntactic construct in C# whatsoever that will cause the C# compiler to emit this instruction.

So what's the problem? Just add some syntax that causes this to be emitted, right?

The problem is: what syntax? In order to ensure that the CLR's physical stack remains aligned correctly, the compiler must know the signature of the method being invoked via the pointer. Of course we already have a mechanism for saying what the signature of a method is: that's called a delegate, and we've already rejected the use of such a thing. Moreover, remember, we are talking here about the physical stack that is actually going to be manipulated, not the CLR's abstract evaluation stack. The signature of the function invoked must include things like whether the function pointer is cdecl or syscall, for instance.

We struggled for some time to come up with something that did not look hideous, and whichever way we tried, it looked more hideous. I actually do not recall what notation we ended up implementing for the prototype; I think I may have blocked it out. I might have it in my notes somewhere, but unfortunately I do not have time to look right now.

The feature is still brought up every now and again. The current management of the C# team has a history with using managed languages in low-level applications, so now might be a good time to pitch it again if you have a strong use case.

like image 196
Eric Lippert Avatar answered Sep 18 '22 22:09

Eric Lippert


While supported by the CLR, the C# language limits you to safe unsafe code. Function pointers fall in the unsafe unsafe category, they can very easily imbalance the stack. A nasty mishap that has long-term consequences, making code misbehave long after the mishap occurred. This site got its name for a good reason, this kind of bug is SOE factorial. Even the C++ compiler adds a runtime check to verify that no stack imbalance occurred.

You still have options. You can use raw function pointers by using Reflection.Emit or C++/CLI. Or achieve the moral equivalent by using Delegate.DynamicInvoke(). The latter is always safe, the CLR performs a runtime check to verify that enough arguments are passed.

Which is the surely the solution you should consider pursuing, albeit that it is not clear why you ask. Delegates are extraordinarily micro-optimized with massive amounts of code in the CLR to make them fast. That code does the equivalent of Reflection.Emit but in machine code. You can't beat it.

like image 35
Hans Passant Avatar answered Sep 17 '22 22:09

Hans Passant


No, there is nothing in C# closer to function pointers from C++ than delegates. C# Pointers may operate on following types:

  • sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
  • Any enum type.
  • Any pointer type.
  • Any user-defined struct type that contains fields of unmanaged types only.

Source: https://msdn.microsoft.com/en-us/library/y31yhkeb.aspx

It is not always possible to give the pointer to function to the user as it is done in native code. C# code is compiled to CLR and not to native code.

In .NET 1.1 there was Econo-JIT mode, in which native code for functions could be deleted after function was invoked. Function could have different address everytime it was invoked.

like image 40
Paweł Stankowski Avatar answered Sep 17 '22 22:09

Paweł Stankowski


C# has no pointers to functions, and as matter of fact the only reason C# has pointers to value types is for interop with C/C++ and Win API. Delegates have you covered.

C# is very different coding paradigm from C++. Do not let semantics similarities confuse you. Two VERY different languages that require VERY different mindset.

like image 21
Riad Baghbanli Avatar answered Sep 18 '22 22:09

Riad Baghbanli