This is part 2 in a series about state and function pointers; part 1 is here.
Unlike most other languages, it is not possible to include any form of state in a function pointer in C. Therefore, it is impossible to fully implement closures in C without the cooperation of the call-site and/or the compiler.
To illustrate what this means in practice, I will refer to my standard example, using a filter function to find all elements in an array that are greater than x
. Since C doesn’t have any such function, I’ll write one myself, inspired by qsort
:
void* filter(void* base, size_t count, size_t elemSize, int (*predicate)(const void *)) { //Magic... }
With this function, one can easily find all elements that are greater than some constant:
int predicate(const void* item) { return *(int*)item > 2; } int arr[] = { 1, 2, 3, 4 }; filter(arr, 4, sizeof(int), &predicate);
However, if we want to replace the hard-coded 2
with a local variable, it becomes more complicated. Since function pointers, unlike delegates, do not have state, there is no simple way to pass the local variable to the function.
The most obvious answer is to use a global variable:
static int minimum; int predicate(const void* item) { return *(int*)item > minimum; } int arr[] = { 1, 2, 3, 4 }; minimum = x; filter(arr, 4, sizeof(int), &predicate);
However, this code will fail horribly if it’s ever run on multiple threads. In simple cases, you can work around that by storing the value in a global thread-local variable (or in fiber-local storage for code that uses fibers). Because each thread will have its own global, the threads won’t conflict with each-other. Obviously, this won’t work if the callback might be run on a different thread.
However, even if everything is running on one thread, this still isn’t enough if the code can be re-entrant, or if the callback might be called after the original function call finishes. This technique assumes that exactly one callback (from a single call to the function that accepted the callback) will be used at any given time. If the callback might be invoked later (eg, a timer, or a UI handler), this method will break down, since all of the callbacks will share the same global.
In these more complicated cases, one can only pass any state with the cooperation of the original function. In this (overly simple) example, the filter
method can be modified to take a context
parameter and pass it to the predicate:
void* filter(void* base, size_t count, size_t elemSize, int (*predicate)(const void *, const void *), const void* context) { //More magic... } int predicate(const void* item, const void* context) { return *(int*)item > *(int*)context; } int arr[] = { 1, 2, 3, 4 }; filter(arr, 4, sizeof(int), &predicate, &x);
To pass around more complicated state, one could pass a pointer to a struct as the context
.
19 comments:
Ahh this brings back memories of the pain of using function pointers with C++, the crazy syntax and workarounds, http://www.newty.de/fpt/callback.html#
I love how C# and .NET makes all this so much easier.
Nice series BTW, cheers
@Matt: With functors, it is now much easier to do this in C++ (not to mention C++0x, which supports closures). Wait for part 5.
The above article is nice and interesting, thank you willing to share! Greetings success of admin Percetakan Murah Rawamangun Jakarta Timur wish you deign to visit my website, thank you :)
I advise you to learn how to brainstorm good college essay topics. It will help you to achieve success in college
Hello, thanks for sharing this interesting information. The material which is mentioned here helps me a lot while I work on my marrakech by george orwell summary task.
Hello there. it's a good item for me. moreover, reading blogs helps me to improve my skills. It's important for my job because I'm a writer at https://300writers.com/case-brief.html
This is a very interesting article for a student who studies information technology at the University. By the way, I write problem solution speech about this.
Phenomenal
salonquickfix
salon quick fix
portable barber chairs
portable barber chairs
Where can I buy a hooded/bonnet hair dryer?
Hooded/Bonnet Hair Dryers Reviews and Recommendations
How to lighten Hair dyed too dark at Salon
Methods to lighten hair dyed to too dark
Most Natural Way to lighten hair color
Marvelous
ज्ञान
राजनीतिक सिद्धांत क्या है
भारतीय संविधान का राजनीतिक दर्शन क्या है
तुलनात्मक राजनीति क्या है
dirty fantasy names
meanest fantasy football names
younghoe koo fantasy football names
Fantasy Football Team Names
Best Fantasy Football Names
Odell Beckham JR Fantasy
Nick Chubb Fantasy Names
Kyler Murray Fantasy Team Names
Clever Fantasy Football Names
Davante Adams Fantasy Names
The c programming language is a simplicity, portability and efficiency. The C++ is a object oriented programming language. The information about the c language is very useful and creative. Using of delegates and the function pointers are explained very well. Traffic Lawyer Petersburg VA
Uncontested divorce process in virginia
Streamline your divorce with our Virginia uncontested divorce process. Our experienced team guides you through the efficient and amicable resolution, minimizing stress and ensuring a smooth legal separation.
New York State Divorce Forms New York State provides various divorce forms, including those for uncontested and contested divorces, available through the court system's website or from legal assistance resources.
Delegates and function pointers are both mechanisms for referencing methods or functions, but they have distinct differences, especially in the context of their usage in programming languages like C# and C/C++ bk lawyer near me
"Delegates" explores the role and responsibilities of representatives in various organizational and governmental contexts. It highlights how delegates influence decision-making and advocate for their constituents' interests. The discussion provides insights into the dynamics of representation and the impact of effective delegation on policy and leadership. An informative read for understanding the importance of delegate roles in governance and management.
divorce laws in virginia
Delegates and function pointers are two key concepts in C# and C programming. Delegates can encapsulate a method's state, allowing it to carry a reference to the object it is associated with. They can be multicast, allowing a single delegate to invoke multiple methods in sequence. Delegates are type-safe, checking method signatures at compile time to avoid runtime errors How Many Points is Careless Driving in New Jersey.
Part 2 of "Delegates vs. Function Pointers" dives into the differences and applications of delegates and function pointers specifically in the C programming language. It explores how function pointers are used to achieve similar behavior to delegates, enabling flexible function calling and callback mechanisms. This blog post is ideal for programmers looking to deepen their understanding of functional programming concepts in C.Traffic Lawyer Bland VAA lawyer, an advocate of justice, navigates the complex legal landscape with expertise and diligence.
Post a Comment