Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Function pointer
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{short description|Pointer that points to a function}} {{Use American English|date=July 2022}} A '''function pointer''', also called a '''subroutine pointer''' or '''procedure pointer''', is a [[pointer (computer programming)|pointer]] referencing executable code, rather than data. [[dereference operator|Dereferencing]] the function pointer yields the referenced [[subroutine|function]], which can be invoked and passed arguments just as in a normal function call. Such an invocation is also known as an "indirect" call, because the function is being invoked ''indirectly'' through a variable instead of ''directly'' through a fixed identifier or address. Function pointers allow different code to be executed at runtime. They can also be passed to a function to enable [[callback (computer programming)|callbacks]]. Function pointers are supported by [[third-generation programming language|third-generation]] [[programming language]]s (such as [[PL/I]], [[COBOL]], [[Fortran]],<ref>{{cite web|url=http://www.esm.psu.edu/~ajm138/fortranexamples.html#ex1|title=Fortran Examples|author=Andrew J. Miller|access-date=2013-09-14}}</ref> [[dBASE]] dBL{{what|date=July 2024}}, and [[C (programming language)|C]]) and [[object-oriented programming]] languages (such as [[C++]], [[C Sharp (programming language)|C#]], and [[D (programming language)|D]]).<ref>{{cite web|url=http://www.newty.de/fpt/intro.html#what|title=The Function Pointer Tutorials|publisher=logo|access-date=2011-04-13|quote=Function Pointers are pointers, i.e. variables, which point to the address of a function|archivedate=2011-05-16|archiveurl=https://web.archive.org/web/20110516153643/http://www.newty.de/fpt/intro.html#what|url-status=deviated}}</ref> ==Simple function pointers== The simplest implementation of a function (or subroutine) pointer is as a [[variable (computer science)|variable]] containing the [[memory address|address]] of the function within executable memory. Older [[third-generation programming language|third-generation languages]] such as [[PL/I]] and [[COBOL]], as well as more modern languages such as [[Pascal (programming language)|Pascal]] and [[C (programming language)|C]] generally implement function pointers in this manner.<ref>{{cite web | access-date = 2011-04-13 | publisher = logo | title = The Function Pointer Tutorials | quote = Important note: A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type! | url = http://www.newty.de/fpt/intro.html#top | archivedate = 2011-05-16 | archiveurl = https://web.archive.org/web/20110516153643/http://www.newty.de/fpt/intro.html#top | url-status = deviated }}</ref> === Example in C === {{See also|#Alternate C and C++ syntax}} The following C program illustrates the use of two function pointers: * ''func1'' takes one double-precision (double) parameter and returns another double, and is assigned to a function which converts centimeters to inches. * ''func2'' takes a pointer to a constant character array as well as an integer and returns a pointer to a character, and is assigned to a [[C string handling]] function which returns a pointer to the first occurrence of a given character in a character array. <syntaxhighlight lang="c"> #include <stdio.h> /* for printf */ #include <string.h> /* for strchr */ double cm_to_inches(double cm) { return cm / 2.54; } // "strchr" is part of the C string handling (i.e., no need for declaration) // See https://en.wikipedia.org/wiki/C_string_handling#Functions int main(void) { double (*func1)(double) = cm_to_inches; char * (*func2)(const char *, int) = strchr; printf("%f %s", func1(15.0), func2("Wikipedia", 'p')); /* prints "5.905512 pedia" */ return 0; } </syntaxhighlight> The next program uses a function pointer to invoke one of two functions (<code>sin</code> or <code>cos</code>) indirectly from another function (<code>compute_sum</code>, computing an approximation of the function's [[Riemann integration]]). The program operates by having function <code>main</code> call function <code>compute_sum</code> twice, passing it a pointer to the library function <code>sin</code> the first time, and a pointer to function <code>cos</code> the second time. Function <code>compute_sum</code> in turn invokes one of the two functions indirectly by dereferencing its function pointer argument <code>funcp</code> multiple times, adding together the values that the invoked function returns and returning the resulting sum. The two sums are written to the standard output by <code>main</code>. <syntaxhighlight lang="c" line="1"> #include <math.h> #include <stdio.h> // Function taking a function pointer as an argument double compute_sum(double (*funcp)(double), double lo, double hi) { double sum = 0.0; // Add values returned by the pointed-to function '*funcp' int i; for (i = 0; i <= 100; i++) { // Use the function pointer 'funcp' to invoke the function double x = i / 100.0 * (hi - lo) + lo; double y = funcp(x); sum += y; } return sum / 101.0 * (hi - lo); } double square(double x) { return x * x; } int main(void) { double sum; // Use standard library function 'sin()' as the pointed-to function sum = compute_sum(sin, 0.0, 1.0); printf("sum(sin): %g\n", sum); // Use standard library function 'cos()' as the pointed-to function sum = compute_sum(cos, 0.0, 1.0); printf("sum(cos): %g\n", sum); // Use user-defined function 'square()' as the pointed-to function sum = compute_sum(square, 0.0, 1.0); printf("sum(square): %g\n", sum); return 0; } </syntaxhighlight> ==Functors== {{main|Function object}} Functors, or function objects, are similar to function pointers, and can be used in similar ways. A functor is an object of a class type that implements the [[function-call operator]], allowing the object to be used within expressions using the same syntax as a function call. Functors are more powerful than simple function pointers, being able to contain their own data values, and allowing the programmer to emulate [[closure (computer programming)|closures]]. They are also used as callback functions if it is necessary to use a member function as a callback function.<ref>{{cite web | access-date = 2011-04-13 | date = 2005-01-31 | publisher = DevX.com | title = Expertise: Intermediate Language: C++: Use Functor for Callbacks in C++ | quote = If you want to use a member function as a callback function, then the member function needs to be associated with an object of the class before it can be called. In this case, you can use functor [with an example on this page]. | url = http://www.devx.com/tips/Tip/27126}}</ref> Many "pure" object-oriented languages do not support function pointers. Something similar can be implemented in these kinds of languages, though, using [[reference (computer science)|references]] to [[protocol (object-oriented programming)|interfaces]] that define a single [[method (computer programming)|method]] (member function). [[List of CLI languages|CLI languages]] such as [[C Sharp (programming language)|C#]] and [[Visual Basic .NET]] implement [[type safety|type-safe]] function pointers with [[delegate (CLI)|delegate]]s. In other languages that support [[first-class function]]s, functions are regarded as data, and can be passed, returned, and created dynamically directly by other functions, eliminating the need for function pointers. Extensively using function pointers to call functions may produce a slow-down for the code on modern processors, because a [[branch predictor]] may not be able to figure out where to branch to (it depends on the value of the function pointer at run time) although this effect can be overstated as it is often amply compensated for by significantly reduced non-indexed table lookups. ==Method pointers== C++ includes support for [[object-oriented programming]], so classes can have [[method (computer programming)|methods]] (usually referred to as member functions). Non-static member functions (instance methods) have an implicit parameter (the ''[[this (computer programming)|this]]'' pointer) which is the pointer to the object it is operating on, so the type of the object must be included as part of the type of the function pointer. The method is then used on an object of that class by using one of the "pointer-to-member" operators: <code>.*</code> or <code>->*</code> (for an object or a pointer to object, respectively).{{Dubious|date=December 2022}} Although function pointers in C and C++ can be implemented as simple addresses, so that typically <code>sizeof(Fx)==sizeof(void *)</code>, member pointers in C++ are sometimes implemented as "[[fat pointer]]s", typically two or three times the size of a simple function pointer, in order to deal with [[virtual methods]] and [[virtual inheritance]]{{Citation needed|date=August 2011}}. == In C++ == In C++, in addition to the method used in C, it is also possible to use the C++ standard library class template {{mono|std::function}}, of which the instances are function objects: <syntaxhighlight lang="cpp"> #include <iostream> #include <functional> using namespace std; static double derivative(const function<double(double)> &f, double x0, double eps) { double eps2 = eps / 2; double lo = x0 - eps2; double hi = x0 + eps2; return (f(hi) - f(lo)) / eps; } static double f(double x) { return x * x; } int main() { double x = 1; cout << "d/dx(x ^ 2) [@ x = " << x << "] = " << derivative(f, x, 1e-5) << endl; return 0; } </syntaxhighlight> === Pointers to member functions in C++ === {{See also|#Alternate C and C++ syntax}} This is how C++ uses function pointers when dealing with member functions of classes or structs. These are invoked using an object pointer or a this call. They are type safe in that you can only call members of that class (or derivatives) using a pointer of that type. This example also demonstrates the use of a typedef for the pointer to member function added for simplicity. Function pointers to static member functions are done in the traditional 'C' style because there is no object pointer for this call required. <syntaxhighlight lang="cpp"> #include <iostream> using namespace std; class Foo { public: int add(int i, int j) { return i+j; } int mult(int i, int j) { return i*j; } static int negate(int i) { return -i; } }; int bar1(int i, int j, Foo* pFoo, int(Foo::*pfn)(int,int)) { return (pFoo->*pfn)(i,j); } typedef int(Foo::*Foo_pfn)(int,int); int bar2(int i, int j, Foo* pFoo, Foo_pfn pfn) { return (pFoo->*pfn)(i,j); } typedef auto(*PFN)(int) -> int; // C++ only, same as: typedef int(*PFN)(int); int bar3(int i, PFN pfn) { return pfn(i); } int main() { Foo foo; cout << "Foo::add(2,4) = " << bar1(2,4, &foo, &Foo::add) << endl; cout << "Foo::mult(3,5) = " << bar2(3,5, &foo, &Foo::mult) << endl; cout << "Foo::negate(6) = " << bar3(6, &Foo::negate) << endl; return 0; } </syntaxhighlight> == Alternate C and C++ syntax == The C and C++ syntax given above is the canonical one used in all the textbooks - but it's difficult to read and explain. Even the above <code>typedef</code> examples use this syntax. However, every C and C++ compiler supports a more clear and concise mechanism to declare function pointers: use <code>typedef</code>, but ''don't'' store the pointer as part of the definition. Note that the only way this kind of <code>typedef</code> can actually be used is with a pointer - but that highlights the pointer-ness of it. === C and C++ === <syntaxhighlight lang="C"> // This declares 'F', a function that accepts a 'char' and returns an 'int'. Definition is elsewhere. int F(char c); // This defines 'Fn', a type of function that accepts a 'char' and returns an 'int'. typedef int Fn(char c); // This defines 'fn', a variable of type pointer-to-'Fn', and assigns the address of 'F' to it. Fn *fn = &F; // Note '&' not required - but it highlights what is being done. // This calls 'F' using 'fn', assigning the result to the variable 'a' int a = fn('A'); // This defines 'Call', a function that accepts a pointer-to-'Fn', calls it, and returns the result int Call(Fn *fn, char c) { return fn(c); } // Call(fn, c) // This calls function 'Call', passing in 'F' and assigning the result to 'call' int call = Call(&F, 'A'); // Again, '&' is not required // LEGACY: Note that to maintain existing code bases, the above definition style can still be used first; // then the original type can be defined in terms of it using the new style. // This defines 'PFn', a type of pointer-to-type-Fn. typedef Fn *PFn; // 'PFn' can be used wherever 'Fn *' can PFn pfn = F; int CallP(PFn fn, char c); </syntaxhighlight> === C++ === These examples use the above definitions. In particular, note that the above definition for <code>Fn</code> can be used in pointer-to-member-function definitions: <syntaxhighlight lang="CPP"> // This defines 'C', a class with similar static and member functions, // and then creates an instance called 'c' class C { public: static int Static(char c); int Member(char c); } c; // C // This defines 'p', a pointer to 'C' and assigns the address of 'c' to it C *p = &c; // This assigns a pointer-to-'Static' to 'fn'. // Since there is no 'this', 'Fn' is the correct type; and 'fn' can be used as above. fn = &C::Static; // This defines 'm', a pointer-to-member-of-'C' with type 'Fn', // and assigns the address of 'C::Member' to it. // You can read it right-to-left like all pointers: // "'m' is a pointer to member of class 'C' of type 'Fn'" Fn C::*m = &C::Member; // This uses 'm' to call 'Member' in 'c', assigning the result to 'cA' int cA = (c.*m)('A'); // This uses 'm' to call 'Member' in 'p', assigning the result to 'pA' int pA = (p->*m)('A'); // This defines 'Ref', a function that accepts a reference-to-'C', // a pointer-to-member-of-'C' of type 'Fn', and a 'char', // calls the function and returns the result int Ref(C &r, Fn C::*m, char c) { return (r.*m)(c); } // Ref(r, m, c) // This defines 'Ptr', a function that accepts a pointer-to-'C', // a pointer-to-member-of-'C' of type 'Fn', and a 'char', // calls the function and returns the result int Ptr(C *p, Fn C::*m, char c) { return (p->*m)(c); } // Ptr(p, m, c) // LEGACY: Note that to maintain existing code bases, the above definition style can still be used first; // then the original type can be defined in terms of it using the new style. // This defines 'FnC', a type of pointer-to-member-of-class-'C' of type 'Fn' typedef Fn C::*FnC; // 'FnC' can be used wherever 'Fn C::*' can FnC fnC = &C::Member; int RefP(C &p, FnC m, char c); </syntaxhighlight> ==PL/I== [[PL/I]] procedures can be nested, that is, procedure A may contain procedure B, which in turn may contain C. In addition to data declared in B, B can also reference any data declared in A, as long as it doesnβt override the definition. Likewise C can reference data in both A and B. Therefore, PL/I ENTRY variables need to contain ''context'',<ref>{{cite book |last1=Abrahams |first1=Paul |title=The PL/I Programming Language |date=March 1978 |publisher=Courant Mathematics and Computing Laboratory, New York University |pages=22β24 |url=http://www.iron-spring.com/abrahams.pdf |access-date=April 4, 2025}}</ref> to provide procedure C with the addresses of the values of data in B and A at the time C was called. ==See also== * [[Delegation (computing)]] * [[Function object]] * [[Higher-order function]] * [[Procedural parameter]] * [[Closure (computer programming)|Closure]] * [[Anonymous function]]s ==References== {{Reflist}} ==External links== * [https://web.archive.org/web/20041013202445/http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.12 FAQ on Function Pointers], things to avoid with function pointers, some information on using [[function object]]s * [http://www.newty.de/fpt/ Function Pointer Tutorials] {{Webarchive|url=https://web.archive.org/web/20180630152057/http://www.newty.de/fpt/ |date=2018-06-30 }}, a guide to C/C++ function pointers, [[callback (computer programming)|callbacks]], and [[function object]]s (functors) * [http://www.codeproject.com/KB/cpp/FastDelegate.aspx Member Function Pointers and the Fastest Possible C++ Delegates], CodeProject article by Don Clugston * [http://www.cplusplus.com/doc/tutorial/pointers.html Pointer Tutorials] {{Webarchive|url=https://web.archive.org/web/20090405234937/http://www.cplusplus.com/doc/tutorial/pointers.html |date=2009-04-05 }}, C++ documentation and tutorials * [http://www.onlinecomputerteacher.net/pointers-in-c.html C pointers explained] {{Webarchive|url=https://web.archive.org/web/20190609120644/http://www.onlinecomputerteacher.net/pointers-in-c.html |date=2019-06-09 }} a visual guide of pointers in C * [http://www.codeproject.com/KB/security/Securefunctionpointer.aspx Secure Function Pointer and Callbacks in Windows Programming], CodeProject article by R. Selvam * [http://publications.gbdirect.co.uk/c_book/chapter5/function_pointers.html The C Book], Function Pointers in C by "The C Book" * [http://www.dbase.com/help/2_80/Language_Definition/IDH_LDEF_FUNCPOINTERS.htm Function Pointers in dBASE dBL], Function Pointer in dBASE dBL [[Category:Pointers (computer programming)]] [[Category:Subroutines]] [[Category:Articles with example C code]] [[Category:Articles with example C++ code]] [[de:Zeiger (Informatik)#Funktionszeiger (Methodenzeiger)]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Citation needed
(
edit
)
Template:Cite book
(
edit
)
Template:Cite web
(
edit
)
Template:Dubious
(
edit
)
Template:Fix
(
edit
)
Template:Main
(
edit
)
Template:Mono
(
edit
)
Template:Reflist
(
edit
)
Template:See also
(
edit
)
Template:Short description
(
edit
)
Template:Use American English
(
edit
)
Template:Webarchive
(
edit
)
Template:What
(
edit
)