Returning function pointer type

CSyntaxTypesFunction Pointers

C Problem Overview


Often I find the need to write functions which return function pointers. Whenever I do, the basic format I use is:

typedef int (*function_type)(int,int);

function_type getFunc()
{
   function_type test;
   test /* = ...*/;
   return test;
}

However this can get cumbersome when dealing with a large number of functions so I would like to not have to declare a typedef for each one (or for each class of functions)

I can remove the typedef and declare the local variable returned in the function as: int (*test)(int a, int b); making the function body look like this:

{
	 int (*test)(int a, int b);
	 test /* = ...*/;
	 return test;
}

but then I do not know what to set for the return type of the function. I have tried:

int(*)(int,int) getFunc()
{
	int (*test)(int a, int b);
	test /* = ...*/;
	return test;
}

but that reports a syntax error. How do I declare the return type for such a function without declaring a typedef for the function pointer. Is it even possible? Also note that I am aware that it seems like it would be cleaner to declare typedefs, for each of the functions, however, I am very careful to structure my code to be as clean and easy to follow as possible. The reason I would like to eliminate the typedefs is that they are often only used to declare the retrieval functions and therefore seem redundant in the code.

C Solutions


Solution 1 - C

int (*getFunc())(int, int) { … }

That provides the declaration you requested. Additionally, as ola1olsson notes, it would be good to insert void:

int (*getFunc(void))(int, int) { … }

This says that getFunc may not take any parameters, which can help avoid errors such as somebody inadvertently writing getFunc(x, y) instead of getFunc()(x, y).

Solution 2 - C

You can probably do something like:

int foo (char i) {return i*2;}

int (*return_foo()) (char c)
{
   return foo;
}

but god, I hope I'll never have to debug you code....

Solution 3 - C

ill leave this here since it was a bit trickier than answers already given, as it takes a function pointer >(int (__cdecl *)(const char *))

and returns a function pointer

>(int (__cdecl *)(const char *))

#include <stdio.h>

int (*idputs(int (*puts)(const char *)))(const char *) {
    return puts;
}

int main(int argc, char **argv)
{
    idputs(puts)("Hey!");

    return 0;
}

Solution 4 - C

While wrapping some C code in C++ classes, I had the same desire as the original poster: return a function pointer from a function without resorting to typedef'ing the function pointer prototype. I hit a problem with C++ const correctness which I thought was worth sharing, even if it's a little off-topic (C++) but it does relate directly to the original question: the syntax for returning a C function pointer without resorting to a typedef.

The code below defines a class A which stores a function pointer and exposes it to the outside world through the get_f() call. This is the function that should return a function pointer without a typedef.

The point (which stumped me for some time) was how to declare that get_f() was a const function, i.e. it wouldn't alter A.

The code contains 2 variants: the first uses a typedef for the function pointer prototype, whilst the second writes everything out in full. The #if switches between the two.

#include <iostream>

int my_f(int i)
{
  return i + 1;
}

#if 0 // The version using a typedef'ed function pointer

typedef int (*func_t)(int);

class A
{
public:
  A(func_t f) : m_f(f) {}
  func_t get_f() const { return m_f; }

private:
  func_t m_f;
};

int main(int argc, char *argv[])
{
  const A a(my_f);
  std::cout << "result = " << a.get_f()(2) << std::endl;
}

#else // The version using explicitly prototyped function pointer    

class A
{
public:
  A(int (*f)(int)) : m_f(f) {}
  int (*get_f() const)(int) { return m_f; }

private:
  int (*m_f)(int);
};

int main(int argc, char *argv[])
{
  const A a(my_f);
  std::cout << "result = " << a.get_f()(2) << std::endl;
}

#endif

The expected/desired output is:

result = 3

The key point is the position of the const qualifier in the line:

int (*get_f() const)(int) { return m_f; }

Solution 5 - C

This is a stupid example, but it's simple and it does not give errors. It's just about declaring static functions:

#include <stdio.h>
#include <stdlib.h>

void * asdf(int);
static int * hjkl(char,float);

main() {
  int a = 0;
  asdf(a);
 }


void * asdf(int a) {return (void *)hjkl; }
static int * hjkl(char a, float b) {int * c; return c;}

Solution 6 - C

I think you've got three options:

  1. Stick with typedef. At the end of the day, it's typedef's job.
  2. Return void* and the casting it.
  3. Reconsider your software architecture. Perhaps you could share with us what you're trying to achieve and see if we can point you toward a better direction.

Solution 7 - C

You can write the following code(It only works in C++11 and above):

//C++11
auto func(...) {
    int (*fptr)(...) ret = ...
    //Do sth.
    return ret;//C++11 compiler will automatically deduce the return type for you
}

Or, if you do not like automatic return type deduction, you can specified the type at the end of the function(Same as above, only in C++11 and above):

//C++11
auto func(...) -> int (*)(...) { /* Do sth. */ }

Solution 8 - C

Simple example fun function which take void as argument which returns function pointer that function should take int* and int* and returns int*

check the link example using typedef https://www.geeksforgeeks.org/returning-a-function-pointer-from-a-function-in-c-cpp/

#include <stdio.h>

int* fun1(int* y, int* z)
{
    static int var = 0;
    var = (*y + *z);
	printf("Inside fun1 = %d\n", var );
	return &var;
}

int* (*fun())(int*,int*)
{
	printf("Inside fun\n");
	return &fun1;
}

int main()
{
    int a=10,b=20;
	int *ptr = NULL;
	int* (*(*fp)())(int*,int*) = &fun;
	ptr=(*fp())(&a,&b);
    printf("*ptr = %d\n", *ptr );
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionS EView Question on Stackoverflow
Solution 1 - CEric PostpischilView Answer on Stackoverflow
Solution 2 - CyosimView Answer on Stackoverflow
Solution 3 - CDmitryView Answer on Stackoverflow
Solution 4 - CduncanView Answer on Stackoverflow
Solution 5 - CNicoMView Answer on Stackoverflow
Solution 6 - CRaffaele RossiView Answer on Stackoverflow
Solution 7 - CJiaHao XuView Answer on Stackoverflow
Solution 8 - CMruthyunjaya MView Answer on Stackoverflow