How to resolve the algorithm Closures/Value capture step by step in the C programming language
How to resolve the algorithm Closures/Value capture step by step in the C programming language
Table of Contents
Problem Statement
Create a list of ten functions, in the simplest manner possible (anonymous functions are encouraged), such that the function at index i (you may choose to start i from either 0 or 1), when run, should return the square of the index, that is, i 2. Display the result of running any but the last function, to demonstrate that the function indeed remembers its value.
Demonstrate how to create a series of independent closures based on the same template but maintain separate copies of the variable closed over. In imperative languages, one would generally use a loop with a mutable counter variable. For each function to maintain the correct number, it has to capture the value of the variable at the time it was created, rather than just a reference to the variable, which would have a different value by the time the function was run. See also: Multiple distinct objects
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Closures/Value capture step by step in the C programming language
-
Function Declarations:
_tmpl()
is an internal function that returns a fixed value (TAG * TAG
).dupf()
takes an integerv
and returns a pointer to a function that is a copy of_tmpl()
but with theTAG
replaced withv
.
-
Function Definition of
dupf()
:- It calculates the size of the function code to be copied (
len
) by subtracting the address of_tmpl
from the address ofdupf
. - It creates a new memory mapping of size
len
, with read-write-execute permissions, and private and anonymous flags. - It copies the code from
_tmpl
to the new memory mapping. - It searches for all occurrences of
TAG
in the copied code and replaces them withv
. - Finally, it returns the address of the new function.
- It calculates the size of the function code to be copied (
-
main()
Function:- It creates an array of function pointers
funcs
. - It iterates through the array and calls
dupf()
to create copies of_tmpl()
with different values ofv
. - It prints the results of calling each function, which are the squares of the values
v
.
- It creates an array of function pointers
Additional Notes:
- This code essentially creates multiple runtime-generated functions that return squared values for different input values.
- It demonstrates the use of memory mapping to create executable code at runtime.
- The code is platform-specific and may only work on certain operating systems (e.g., Linux).
Source code in the c programming language
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
typedef int (*f_int)();
#define TAG 0xdeadbeef
int _tmpl() {
volatile int x = TAG;
return x * x;
}
#define PROT (PROT_EXEC | PROT_WRITE)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS)
f_int dupf(int v)
{
size_t len = (void*)dupf - (void*)_tmpl;
f_int ret = mmap(NULL, len, PROT, FLAGS, 0, 0);
char *p;
if(ret == MAP_FAILED) {
perror("mmap");
exit(-1);
}
memcpy(ret, _tmpl, len);
for (p = (char*)ret; p < (char*)ret + len - sizeof(int); p++)
if (*(int *)p == TAG) *(int *)p = v;
return ret;
}
int main()
{
f_int funcs[10];
int i;
for (i = 0; i < 10; i++) funcs[i] = dupf(i);
for (i = 0; i < 9; i++)
printf("func[%d]: %d\n", i, funcs[i]());
return 0;
}
func[0]: 0
func[1]: 1
func[2]: 4
func[3]: 9
func[4]: 16
func[5]: 25
func[6]: 36
func[7]: 49
func[8]: 64
void init(void)
{
t = intern(lit("t"));
x = intern(lit("x"));
}
val square(val env)
{
val xbind = assoc(env, x); /* look up binding of variable x in env */
val xval = cdr(xbind); /* value is the cdr of the binding cell */
return num(cnum(xval) * cnum(xval));
}
int main(void)
{
int i;
val funlist = nil, iter;
init();
for (i = 0; i < 10; i++) {
val closure_env = cons(cons(x, num(i)), nil);
funlist = cons(func_f0(closure_env, square), funlist);
}
for (iter = funlist; iter != nil; iter = cdr(iter)) {
val fun = car(iter);
val square = funcall(fun, nao);
printf("%d\n", cnum(square));
}
return 0;
}
You may also check:How to resolve the algorithm Create a file on magnetic tape step by step in the Applesoft BASIC programming language
You may also check:How to resolve the algorithm Chinese zodiac step by step in the AutoHotkey programming language
You may also check:How to resolve the algorithm Stack traces step by step in the Icon and Unicon programming language
You may also check:How to resolve the algorithm Longest common subsequence step by step in the C programming language
You may also check:How to resolve the algorithm Hello world/Web server step by step in the Sidef programming language