How can I concatenate (or merge) two functions that take no arguments and return nothing into one function? In JavaScript I would do this:
function f1() {
console.log("f1 called");
}
function f2() {
console.log("f2 called");
}
function function_concat(fa, fb) {
var final = function() {
fa();
fb();
};
return final;
}
var merged = function_concat(fa, fb);
merged();
In C, this is what I have:
#include <stdio.h>
#include <stdlib.h>
typedef void (*fptr)(void);
void f1() {
printf("f1 called");
}
void f2() {
printf("f2 called");
}
fptr function_concat(fa, fb) {
// What to do here??
}
int main(int argc, const char **argv) {
fptr merged = function_concat(f1, f2);
fptr();
}
I know I'll have to return a static pointer, but I can't define a function in a function in C which makes it hard to create new functions if I'm already in a function. Does anybody know a way to do this?
You can't define function at runtime in C, so you're only option is to implement some sort of proxy. You can use global variables to refer to the function pointers, but to give an implicit answer, you can't really emulate this in C.
If you ever need to change the interface of fa_ and fb_ you'll need to call function_concat again, or set the global variables directly, but at that point you wouldn't need the proxy function.
static fptr fa_, fb_;
void function_concat_proxy() {
fa_();
fb_();
}
fptr function_concat(fptr fa, fptr fb) {
fa_ = fp;
fb_ = fb;
return function_concat_proxy;
}
Let me preface by saying that trying to emulate the behavior of a language which treats functions as first class citizens is a, to say the least, weird request.
Alternatively, one thing you could create a new typedef for a type that takes two function pointers and then call it:
typedef void (*mptr)(fptr, fptr);
With function_concat looking like:
void function_concat(fptr fa, fptr fb) {
fa();
fb();
}
and main:
int main(int argc, const char **argv) {
mptr merged = function_concat;
merged(f1, f2);
}
Which is similar to just calling function_concat(f1, f2) only via a function pointer now. Apparently not exactly what you're looking for but, alas, I'll leave it here for reference.
You cannot do this in c. What you can do is to call your 2 functions in the function_concat :
void function_concat(fa, fb) {
fa();
fb();
}
Related
I'm working on a network service that based on commands it receives over the network, it has workers perform different jobs. I want to have a log entry for every time a certain worker is tasked with doing some job.
I have a function (say function_caller) which, among other things, calls another function which it receives its pointer as an argument. I'd like to have my logger notify what kind of function function_caller calls.
Originally I wanted the function_caller to receive some enum instead of a function pointer, provide the enum to the logger, and then use a helper function which returns a suitable pointer based on the enum. However, function_caller is already deeply tangled in the codebase I'm working on, and it looks like it would be a lot of work to refactor all the functions that call function_caller to choose the right enum and use a new argument.
So my next idea was having a switch that for every function pointer will have some string representation of, but I've never stumbled upon something like that (and struggled to find anyone even mentioning such an idea on Google), so I have a feeling I might be missing some serious downsides to this option.
The only significant problem I see is that every developer that decides to pass a new kind of function pointer to function_caller will have to somehow know to update the switch, otherwise it will fail.
Am I missing anything else? Or maybe there's some other approach I should consider?
How about something like this? Instead of a switch, store a table of functions and their name strings. The table can even be kept dynamically updated, unlike a switch case. You will not need to walk along the edge of the standard as well!
#include <stdio.h>
typedef void (*callback_t) (void);
void first (void) { printf("%d", 1); };
void second (void) { printf("%d", 2); };
void third (void) { printf("%d", 3); };
typedef struct fntable_t
{
callback_t fn;
char *name;
} fntable_t;
fntable_t fntable[] =
{
{ first, "first" },
{ second, "second" },
{ third, "third" }
};
char* log_str(callback_t c)
{
for(int i = 0; i < sizeof(fntable) / sizeof(fntable_t); i++)
{
if(fntable[i].fn == c)
return fntable[i].name;
}
return "unknown";
}
void function_caller(callback_t c)
{
printf("%s",log_str(c));
c();
}
int main(void)
{
function_caller(first);
function_caller(second);
function_caller(third);
return 0;
}
You could replace function_caller with a wrapper macro of the same name that calls the renamed function function_caller_internal which gets an additional string argument. The wrapper macro can then pass an additional stringified function name.
This works only if function_caller is always called with a function name, not a function pointer variable.
Example:
#include <stdio.h>
static void funcA(void)
{
printf("This is funcA\n");
}
static void funcB(void)
{
printf("This is funcB\n");
}
/* renamed function gets an additional string argument */
static void function_caller_internal(void (*func)(void), const char *name)
{
printf("calling %s\n", name);
func();
}
/* wrapper macro stringifies the function name to pass it the additional argument */
#define function_caller(func) function_caller_internal(func, #func)
int main(void)
{
/* unchanged calls */
function_caller(funcA);
function_caller(funcB);
return 0;
}
This prints
calling funcA
This is funcA
calling funcB
This is funcB
If you can change the API of the functions, then consider using __func__ to get the textual name of each function. If you can have a function pointer type along the lines of this:
typedef void func_t (const char** name);
Then you can have each function return its name to the caller.
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
Example:
#include <stdio.h>
typedef void func_t (const char** name);
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
const char* function_caller (func_t* func, const char** name)
{
func(name);
return *name;
}
int main(void)
{
static func_t*const func [] =
{
foo,
bar,
};
const char* name;
for(size_t i=0; i<sizeof func/sizeof *func; i++)
{
puts( function_caller(func[i], &name) );
}
}
Assuming your codebase has sane variable names and function names, you can add a char * argument to your function caller:
void function_caller(char *name, int fpnt());
and then provide a macro:
#define function_caller_autoname(fpnt) function_caller(#fpnt, fpnt)
(Or, for spaghetti code, you can provide a macro with the same name as the function).
The #fpnt will be expanded by the proceprocessor to a string literal with the function name.
Then when your codebase called:
function_caller(some_function)
refactor it to:
function_caller_autoname(some_function)
# will be expanded to by the processor:
# function_caller("some_function", some_function)
or refactor it manually to provide the name/identificator/description of the function:
function_caller("Some function: ", some_function)
That way you can pass a custom string that describes the function along with the pointer. Also, each developer can pass a custom description string.
I want to understand why we write this DWORD MyExceptionHandler(void);
and this int foo(char *buf);, two times in this example.
Why we just write those functions without writing the definition:
DWORD MyExceptionHandler(void);
int foo(char *buf);
Example:
#include <windows.h>
#include <stdio.h>
DWORD MyExceptionHandler(void);
int foo(char *buf);
int main(int argc, char *argv[])
{
HMODULE l;
l = LoadLibrary("msvcrt.dll");
l = LoadLibrary("netapi32.dll");
printf("\n\nHeapoverflow program.\n");
if(argc != 2)
return printf("ARGS!");
foo(argv[1]);
return 0;
}
DWORD MyExceptionHandler(void)
{
printf("In exception handler....");
ExitProcess(1);
return 0;
}
int foo(char *buf)
{
HLOCAL h1 = 0, h2 = 0;
HANDLE hp;
__try{
hp = HeapCreate(0,0x1000,0x10000);
if(!hp){
return printf("Failed to create heap.\n");
}
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,260);
printf("HEAP: %.8X %.8X\n",h1,&h1);
// Heap Overflow occurs here:
strcpy(h1,buf);
// This second call to HeapAlloc() is when we gain control
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,260);
printf("hello");
}
__except(MyExceptionHandler())
{
printf("oops...");
}
return 0;
}
A function has to be declared before you can call it. There are two ways to do it:
You can put the entire function definition before the definitions of any functions that call it. The definition serves as a declaration as well.
You can put a prototype of the function before the definitions of any functions that call it. This simply declares the function's parameter and return types. The definition can be put later, or even in another compilation unit that you link with later.
Many programmers like to put prototypes of all their functions at the beginning of the file. This allows them to put the definitions in any order, rather than keeping track of which calls which so you can get all the dependencies right. In particular, it allows you to put the main() function first, which can make it easier to follow the logic of the program.
I have an issue with a customer. He's asking me to set up a DB table with key/values where the values are names of C functions.
He wants me to build a generic executable that will take the records of that table and call the functions stored into a C library. He wants to be able to insert or update new pairs of key/values and without modifying the executable, be able to change the function called.
As an example, I wil l post now something very similar:
int sum(int a, int b)
{
return a+b;
}
int sub(int a, int b)
{
return a-b;
}
int (*funcion) (int,int);
{
...
funcion = (void*)"sum";
x = funcion(4,3);
funcion = (void*)"sub";
x = funcion(4,3);
}
Is this going to work?
Thanks!
You need a "lookup table".
The problem is that you need to define all functions which could be called before compilation. In order to add new functions you need to change the code. But if thats ok for you this should do the job.
#include <stdio.h>
#include <string.h>
typedef enum
{
_printf,
_scanf,
} functions;
void *get_function_ptr(int func)
{
switch (func)
{
case _printf: return &printf;
case _scanf: return &scanf;
default: return NULL;
}
}
int main(int argc, char **argv)
{
if (strcmp(argv[1], "printf") == 0)
{
void (*ptr)(char *, char *) = get_function_ptr(_printf);
(*ptr)("%s", "hi there");
}
}
Another way would, as in the comment above said, a dynamic linked library, but then you are OS dependend.
I am a newbie to C. I am trying to implement callback function using function pointers.
I am getting an error
:test_callback.c:10: error: expected identifier or ‘(’ before ‘void’
when I try to compile the following program:
#include<stdio.h>
void (*callback) (void);
void callback_proc ()
{
printf ("Inside callback function\n");
}
void register ((void (*callback) (void)))
{
printf ("Inside registration \n");
callback (); /* Calling an initial callback with function pointer */
}
int main ()
{
callback = callback_proc;/* Assigning function to the function pointer */
register (callback);/* Passing the function pointer */
return 0;
}
What is this error?Can anyone help?
register is a C keyword: Use another name for the function.
You have extra parantheses around the callback parameter. It should be:
void funcName(void (*callback) (void))
I would recommend to use a typedef
#include<stdio.h>
typedef void (*callback_t) (void);
callback_t callback;
void callback_proc(void)
{
printf ("Inside callback function\n");
}
void reg( callback_t _callback )
{
printf ("Inside registration \n");
_callback();
}
int main ()
{
callback = callback_proc;
reg(callback);
return 0;
}
EDIT: removed the register issue
You can't use 'register' as a function name as it's a C keyword.
2 problems:
you can't use the name register as it's a keyword (not used often anymore, but it's still there)
change the definition of the function from
void wasRegister((void (*callback) (void)))
to:
void wasRegister(void (*callback) (void))
(get rid of the parens around the parameter's declaration.
Also you might get a warning about callback_proc() not having a matching delaration to the callback variable (depending on how you compile the program - as C or C++), so you might want to change its declaration to:
void callback_proc (void)
to make it explicit that it takes no parameters.
Have a look at type safe callbacks from ccan. Its one thing to expose a typed function pointer for the world to use, its another to ensure sane casting.
#include<stdio.h>
typedef void (*callback_func) (void);
static callback_func the_callback = 0;
void process (void)
{
printf ("Inside process function\n");
}
void callback_register (callback_func cb)
{
the_callback = cb;
printf ("Inside registration \n");
}
void callback(void)
{
the_callback();
}
int main (void)
{
callback_register(process); /* Passing the function pointer */
callback();
return 0;
}
Declaring the_callback static would make more sense if this code was modularized and then you would be forced to call callback_register in order to set it, and callback in order to call it - the_callback would not be accessible outside of the implementation (.c) only the function declarations would be in the header (.h).
I am doing a recursive program and I am getting an error about conflicting types:
void* buddyMalloc(int req_size)
{
// Do something here
return buddy_findout(original_index,req_size); // This is the recursive call
}
void *buddy_findout(int current_index,int req_size)
{
char *selected = NULL;
if(front!=NULL)
{
if(current_index==original_index)
{
// Do something here
return selected;
}
else
{
// Do Something here
return buddy_findout(current_index+1,req_size);
}
}
else
{
return buddy_findout(current_index-1,req_size);
}
}
Error:
buddy.c: At top level:
buddy.c:76: error: conflicting types for ‘buddy_findout’
buddy.c:72: note: previous implicit declaration of ‘buddy_findout’ was here
Please note the file buddy.c in which I am defining this does not contain main and is linked with several other .c files.
You can't use a function prior to its proper definition without a prototype. buddy_malloc() is using buddy_findout() before it is prototyped or defined, which the compiler will treat as a definition.
Prototype buddy_findout() prior to defining buddy_Malloc(), or define buddy_findout() prior to defining buddy_Malloc().
I suggest prototypes, i.e:
void *buddy_Malloc(int);
void *buddy_findout(int, int);
... Just under your last #include
This avoids any confusion on the order that you define things. Also, consider using size_t (the largest unsigned int type available on the architecture) instead of signed integers when specifying sizes.
Here is your code (corrected) using both methods. Method 1 - using prototypes:
void *buddy_Malloc(int);
void *buddy_findout(int, int);
void* buddyMalloc(int req_size)
{
//Do something here//
return buddy_findout(original_index,req_size); //This is the recursive fn I call//
}
void *buddy_findout(int current_index,int req_size)
{
char *selected = NULL;
if(front!=NULL)
{
if(current_index==original_index)
{
//Do something here//
return selected ; //
}
else
{
//Do Something here//
return buddy_findout(current_index+1,req_size);
}
}
else
{
return buddy_findout(current_index-1,req_size);
}
}
And method 2, just re-ordering:
void *buddy_findout(int current_index,int req_size)
{
char *selected = NULL;
if(front!=NULL)
{
if(current_index==original_index)
{
//Do something here//
return selected ; //
}
else
{
//Do Something here//
return buddy_findout(current_index+1,req_size);
}
}
else
{
return buddy_findout(current_index-1,req_size);
}
}
void* buddyMalloc(int req_size)
{
//Do something here//
return buddy_findout(original_index,req_size); //This is the recursive fn I call//
}
In some circles it is sort of considered an art to not need prototypes for static functions, it kind of demonstrates the program was planned out in someone's head before code was written. I don't have much to say about that either way, other than recommending prototypes even for static functions to those who are still learning the nuts and bolts of C.
If buddy_* is going to be exposed for other modules to use, you really need prototypes. Its hard to tell if you intend these to be static or not.
Edit:
If you are putting the prototypes in an external header file, you need to use include guards to ensure that each module includes them only once (and doesn't re-define them to be the exact same thing).
Here is a sample buddy.h:
#ifndef BUDDY_H
#define BUDDY_H
void *buddy_Malloc(int);
void *buddy_findout(int, int);
#endif /* BUDDY_H */
The preprocessor will then keep your modules from throwing that error.
I guess this has to be with missing prototypes.
Add the function prototype of
void *buddy_findout(int current_index,int req_size);
before the function buddyMalloc
buddy_findout is declared to return a pointer to void, but in one place you're attempting to return selected, which is a pointer to char. As others have already pointed out, you also need a prototype for buddy_findout:
void *buddy_findout(int, int);
void *buddy_malloc(int req_size) {
return buddy_findout(original_index,req_size);
}
void *buddy_findout(int current_index, int req_size) {
// ...
if (current_index == original_index)
return (void *)selected;
// ...
}