tags:

views:

307

answers:

9

hi, how can i dynamically create a function in c?

I try to summarize my C problem as follows: i have a matrix and i want to be able to use some function to generate its elements function has no arguments hence i define the following :

typedef double(function)(unsigned int,unsigned int);

/* writes f(x,y) to each element x,y of the matrix*/
void apply(double ** matrix, function * f);

now i need to generate constant functions within the code. i thought about creating a nested function and returning its pointer, but gcc manual (which allows nested functions) says

"If you try to call the nested function through its address after the containing function has exited, all hell will break loose."

which i would kind of expect from this code...

function * createConstantFunction(const double value){
 double function(unsigned int,unsigned int){
   return value;
 }
 return &function;
}

so how can i get it to work?

thanks!

+2  A: 

If you want to write code on the fly for execution, nanojit might be a good way to go.

In your code above, you're trying to create a closure. C doesn't support that. There are some heinous ways to fake it, but out of the box you're not going to be able to runtime bind a variable into your function.

plinth
+13  A: 

C is a compiled language. You can't create code at run-time "in C"; there is no specific C support to emit instructions to memory and so on. You can of course try just allocating memory, making sure it's executable, and emit raw machine code there. Then call it from C using a suitable function pointer.

You won't get any help from the language itself though, this is just like generating code and calling it in BASIC on an old 8-bit machine.

unwind
+5  A: 

One way of doing would be to write a standard C file with the set of functions you want, compile it via gcc and the load it as a dynamic library to get pointers to the functions.

Ultimately, it probably would be better if you were able to specify your functions without having to define them on-the-fly (like via having a generic template function that takes arguments that define its specific behavior).

Romain
+1  A: 

As unwind already mentioned, "creating code at runtime" is not supported by the language and will be a lot of work.

I haven't used it myself, but one of my co-workers swears by Lua, an "embedded language". There is a Lua C API which will (theoretically, at least) allow you to perform dynamic (scripted) operations.

Of course, the downside would be that the end user may need some sort of training in Lua.

It may be a dumb question, but why does the function have to be generated within your application? Similarly what advantage does the end-user get from generating the function themselves (as opposed to selecting from one or more predefined functions that you provide)?

Richard J Foster
+1  A: 

This mechanism is called reflection where code modifies its own behavior at runtime. Java supports reflection api to do this job.
But I think this support is not available in C.

Sun web site says :

Reflection is powerful, but should not be used indiscriminately. If it is possible to perform an operation without using reflection, then it is preferable to avoid using it. The following concerns should be kept in mind when accessing code via reflection.

Drawbacks of Reflection

Performance Overhead Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

Security Restrictions

Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.

Exposure of Internals

Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform. .

atv
+1  A: 

It looks like you're coming from another language where you commonly use this type of code. C doesn't support it and it although you could certainly cook up something to dynamically generate code, it is very likely that this isn't worth the effort.

What you need to do instead is add an extra parameter to the function that references the matrix it is supposed to work on. This is most likely what a language supporting dynamic functions would do internally anyway.

Frederik Slijkerman
+1  A: 

If you really need to dynamically create the functions, maybe an embedded C interpreter could help. I've just googled for "embedded C interpreter" and got Ch as a result:

http://www.softintegration.com/

Never heard of it, so I don't know anything about it, but it seems to be worth a look.

Secure
+1  A: 

Using FFCALL, which handles the platform-specific trickery to make this work:

#include <stdio.h>
#include <stdarg.h>
#include <callback.h>

static double internalDoubleFunction(const double value, ...) {
    return value;
}
double (*constDoubleFunction(const double value))() {
    return alloc_callback(&internalDoubleFunction, value);
}

main() {
    double (*fn)(unsigned int, unsigned int) = constDoubleFunction(5.0);
    printf("%g\n", (*fn)(3, 4));
    free_callback(fn);
    return 0;
}

(Untested since I don't have FFCALL currently installed, but I remember that it works something like this.)

ephemient
+2  A: 

You must be familiar with some programming language which supports closure mechanism ,don't you? Unfortunately, C does not support closure like that itself.

You could find out some useful libraries which simulate closure in C if you insisted on closure. But most of those libraries are complex and machine-dependence.
Alternatively, you can change your mind to agree with the C-style closure if you could change the signature of double ()(unsigned,unsigned);.

In C, functions itself has no data (or context) except the parameters of it and the static variable which it could access.
So the context must be passed by yourself. Here is a example using extra parameter :

// first, add one extra parameter in the signature of function.
typedef double(function)(double extra, unsigned int,unsigned int);

// second, add one extra parameter in the signature of apply
void apply(double* matrix,unsigned width,unsigned height, function* f, double extra)
{
        for (unsigned y=0; y< height; ++y)
            for (unsigned x=0; x< width ++x)
                    matrix[ y*width + x ] = f(x, y, extra);
        // apply will passing extra to f
}

// third, in constant_function, we could get the context: double extra, and return it
double constant_function(double value, unsigned x,unsigned y) { return value; }

void test(void)
{
        double* matrix = get_a_matrix();
        // fourth, passing the extra parameter to apply
        apply(matrix, w, h, &constant_function, 1212.0);
        // the matrix will be filled with 1212.0
}

Is a double extra enough? Yes, but only in this case.
How should we do if more context is required?
In C, the general purpose parameter is void*, we can pass any context though one void* parameter by passing the address of context.

Here is another example :

typedef double (function)(void* context, int, int );
void apply(double* matrix, int width,int height,function* f,void* context)
{
        for (int y=0; y< height; ++y)
            for (int x=0; x< width ++x)
                    matrix[ y*width + x ] = f(x, y, context); // passing the context
}
double constant_function(void* context,int x,int y)
{
        // this function use an extra double parameter \
        //    and context points to its address
        double* d = context;
        return *d;
}
void test(void)
{
        double* matrix = get_a_matrix();
        double context = 326.0;
        // fill matrix with 326.0
        apply( matrix, w, h, &constant_function, &context);
}

(function,context) pair like &constant_function,&context is the C-style closure.
Each function(F) that needs a closure must has one context parameter which will be passed to closure as its context. And the caller of F must use a correct (f,c) pair.

If you can change the signature of function to fit to C-style closure, your code will be simple and machine-independence.
If couldn't (function and apply is not written by you), try to persuade him to change his code.
If failed, you have no choice but to use some closure libraries.

OwnWaterloo