Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fake anonymous functions in C

In this SO thread, Brian Postow suggested a solution involving fake anonymous functions:

make a comp(L) function that returns the version of comp for arrays of length L... that way L becomes a parameter, not a global

How do I implement such a function?

like image 741
Alexandru Avatar asked Oct 30 '09 15:10

Alexandru


People also ask

Are there anonymous functions in C?

The anonymous function is not supported by standard C programming language, but supported by some C dialects, such as GCC and Clang.

Are anonymous functions bad?

Anonymous functions aren't so bad when they have just one line of code, but multi lined (especially nested) anonymous functions can quickly cause even the most simple code to be unreadable.

Which function is known as anonymous function give example?

An anonymous function is a function that was declared without any named identifier to refer to it. As such, an anonymous function is usually not accessible after its initial creation. Normal function definition: function hello() { alert('Hello world'); } hello();

What are two common uses of anonymous functions?

We can use the anonymous function in JavaScript for several purposes. Some of them are given below: Passing an anonymous function to other function as its argument. We can also use an anonymous function as an argument for another function.


2 Answers

See the answer I just posted to that question. You can use the callback(3) library to generate new functions at runtime. It's not standards compliant, since it involves lots of ugly platform-specific hacks, but it does work on a large number of systems.

The library takes care of allocating memory, making sure that memory is executable, and flushing the instruction cache if necessary, in order to ensure that code which is dynamically generated (i.e. the closure) is executable. It essentially generates stubs of code that might look like this on x86:

  pop %ecx
  push $THUNK
  push %ecx
  jmp $function
THUNK:
  .long $parameter

And then returns the address of the first instruction. What this stub does is stores the the return address into ECX (a scratch register in the x86 calling convention), pushes an extra parameter onto the stack (a pointer to a thunk), and then re-pushes the return address. Then, it jumps to the actual function. This results in the function getting fooled into thinking it has an extra parameter, which is the hidden context of the closure.

It's actually more complicated than that (the actual function called at the end of the stub is __vacall_r, not the function itself, and __vacall_r() handles more implementation details), but that's the basic principle.

like image 134
Adam Rosenfield Avatar answered Oct 26 '22 12:10

Adam Rosenfield


I don't believe you can do that with C99 -- there's no partial application or closure facility available unless you start manually generating machine code at runtime.

Apple's recently proposed blocks would work, though you need compiler support for that. Here's a brief overview of blocks. I have no idea when/if any vendor outside apple will support them.

like image 24
Ivatar Avatar answered Oct 26 '22 12:10

Ivatar