Function Pointers
Prerequisites
1. What is a Function Pointer?
A function pointer is a variable that stores the address of a function. Just like pointers to variables, but pointing to functions
1
| return_type (*pointer_name)(parameter_types);
|
Use when:
- You need C-style callbacks
- You want low-overhead dynamic dispatch
- You are working with legacy or embedded systems
✔️ Example
1
2
3
4
5
6
7
8
9
10
11
12
13
| #include <iostream>
int add(int a, int b)
{
return a + b;
}
int main()
{
int (*funcPtr)(int, int) = add;
std::cout << funcPtr(2, 3); // 5
}
|
funcPtr now points to add
2. Why Use Function Pointers?
2-1. Callback Functions
1
2
3
4
| void execute(int (*func)(int, int))
{
std::cout << func(2, 3);
}
|
2-2. Dynamic Behavior
1
2
3
4
5
6
7
8
9
10
| int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int (*op)(int, int);
op = add;
std::cout << op(5, 3); // 8
op = sub;
std::cout << op(5, 3); // 2
|
2-3. Table of Functions
1
2
3
4
5
6
7
| int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int (*ops[2])(int, int) = {add, sub};
std::cout << ops[0](3, 2); // add
std::cout << ops[1](3, 2); // sub
|
✔️ Direct Call
✔️ Function Pointer Call
| Aspect | Direct Call | Function Pointer |
|---|
| Inline Optimization | ✅ Possible | ❌ Not possible |
| Branch Prediction | Better | Slightly worse |
| Overhead | Minimal | Small overhead |
| Flexibility | Low | High |
3-1. No Inlining
1
| int add(int a, int b) { return a + b; }
|
Compiler may inline:
1
| int result = 2 + 3; // optimized
|
But with function pointer:
Compiler cannot inline (target unknown at compile time)
3-2. Indirect Call
Function pointer introduces an indirect jump
1
2
| Direct call: call add
Pointer call: call [address]
|
This affects CPU pipeline & branch prediction
- Usually very small overhead
- Becomes noticeable in:
- tight loops
- high-frequency calls
- performance-critical systems
4. Function Pointer vs Modern Alternatives
✔️ Function Pointer
✔️ std::function
1
2
3
| #include <functional>
std::function<int(int, int)> func = add;
|
More flexible but slower
✔️ Lambda
1
| auto func = [](int a, int b) { return a + b; };
|
Often inlined → fastest
| Method | Speed | Flexibility |
|---|
| Direct Call | 🔥 Fastest | ❌ |
| Lambda | 🔥 Fast | ✅ |
| Function Pointer | ⚡ Medium | ✅ |
| std::function | 🐢 Slowest | 🔥 Most flexible |
5. Common Mistakes
❌ Forgetting pointer syntax
1
| int *func(int, int); // ❌ wrong
|
✔️ Correct:
❌ Null pointer call
1
2
3
| int (*func)(int, int) = nullptr;
func(2, 3); // ❌ crash
|
✔️ Always check:
1
2
3
4
| if (func)
{
func(2, 3);
}
|
6. Function Pointer Typedef
1
2
3
| typedef int (*FuncPtr)(int, int);
FuncPtr f = add;
|
Or (modern C++):
1
2
3
| using FuncPtr = int (*)(int, int);
FuncPtr f = add;
|
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #include <iostream>
using Operation = int (*)(int, int);
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
int compute(Operation op, int a, int b)
{
return op(a, b);
}
int main()
{
std::cout << compute(add, 2, 3); // 5
std::cout << compute(mul, 2, 3); // 6
}
|