C Function Pointers - What happens when you drop an argument? - c

all. I'm currently working with an old established code base for a new project which is basically undocumented (i.e. averages 1 one-line comment per file). I just ran into something which I haven't seen before and am not quite sure how to interpret.
Firstly, they define a function type and a function in the header file (.h) in the form:
typedef void (*SOME_FUNCTION)(void *data, EXECUTION_CONTEXT *ec);
void add_function(SOME_FUNCTION aFunction, void *data);
In the main source file (.c), there is a function defined:
void add_function(void (*f)(void *data), void *data)
{
(Some code here)
}
So okay, there's a function pointer... but what the heck happened to the second argument, ec? Why would someone use a code design like this? For reference, when the function add_function is used, it is used in this sort of form:
void passedFunction(void *data, EXECUTION_CONTEXT *ec)
{
(Stuff the function does.)
}
void CallingFunction()
{
data = (some data stuff);
add_function((SOME_FUNCTION)passedFunction, data);
}
So, as you can see, the passed functions use the correct form that fits the original SOME_FUNCTION argument signature, but the definition for the add_function arguments is short by one argument.

Formally, the results are undefined: you are only permitted to call a function via a function pointer if the types match.
As for what actually happens, it depends on the calling convention and what the function does with the arguments. Chances are, the results aren't going to be good.

To add on James' answer:
Since the default calling convention is most likely cdecl, the call site is responsible for cleaning up the stack after passedFunction returns. Since the call site knows that it passed just 1 argument to the callee, the compiler can clean up the stack normally (even though technically this is undefined behavior).
Change the calling convention on passedFunction to stdcall though, and you 're in for some fireworks.

From the example code below, it doesn't appear that the variable(s) that are defined in the function pointer matters during the check. The code below compiles without warning.
#include <stdio.h>
int temp(int (*m)());
int main(int argc, char *argv[]) {
return temp(main);
}
int temp(int (*m)()) {
return 1;
}
However, the code below throws an error.
#include <stdio.h>
int temp(void (*m)());
int main(int argc, char *argv[]) {
return temp(main);
}
int temp(void (*m)()) {
return 1;
}
Due to this; it seems that the compiler (at least in my case GCC) only cares what the return value of the function pointer will be. The interesting thing here is that you CAN send the parameters correctly but if you do NOT specify the parameter (in our example m()), then the variables in m() when called will be junk.

Related

C Global Variable Code giving an compilation error

So I'm new to c and wrote some code but i'm not sure why i'm getting an error when i try to run it.
int GlobalVariable=0;
int main()
{
int LocalVariable=0; //can be used within main()
dis();
printf(GlobalVariable);
return 1;
}
int dis()
{
GlobalVariable=5; //Can be accessed in any functions and made changes to it
}
Here is the prototype of printf function:
int printf(const char * restrict format, ...);
And look what you are typing:
int GlobalVariable=0;
printf(GlobalVariable);
The problem is that you used a function without first telling the compiler about it.
In this case you must provide function prototype as the function definition itself is provided after main
int dis( void ); // function prototype
int main()
{
...
}
int dis() // function definition
{
...
}
Alternatively, you can put the function definition before main(). But usually it would be better to have function prototypes before main() and (usually) even better to put the prototypes in a separate header file - that way it'd be easier to look straight into the main program without being bother about other function details.

How to obtain the function name and number of arguments from a function in C?

Lets say I am maintaining an array of function structures in which I store API information.
This is definition of function structure:
typedef struct function {
void (*func)(long, ...);
char* name;
int argc;
char *argv[];
} function;
function api_list[N]
I would maintain a list of such structures.
Now given any function, I want to write a function Register(api_list, fp)
which adds one such structure initialized with details of function fp.
int fp(int a, int b) {
return a+b;
}
Register(api_list, fp);
How to do it in C?
I believe you will need to either parse the C function declarations yourself or find some other code to do it. I looked around a bit and there's code for this in the Ruby FFI, PerlXS and other script binding generators like SWIG. I also saw the XML plugin to GCC which generates XML describing the program.
If you look up C's BNF or EBNF definitions and know a bit of parsing theory, figuring out C functions is not hard. C++ is a whole other ball o' wax.
Note: I think I misunderstood. The following is for calling C functions with unknown number and types of arguments. Not for finding out what the function signature already looks like.
Look at the FFI (Foreign Function Interface) library which can be found at Sourceware:
https://sourceware.org/libffi/
This is packaged with many Linux systems already because it is heavily used by interpreted languages that need to call C functions.
Now given any function, I want to write a function Register(api_list, fp) which adds one such structure initialized with details of function fp.
There is no way to do this in Standard C. The main reason is you need keep track of original definition of an function to call it via such structure. You actually could store every function pointer as struct member:
void (*func)()
that is fine, but any attempt to call such function when type is not compatible (both parameters and return type are not the same) with original definition will invoke undefined behaviour. This means, that you would need to cast it properly for every call:
((int (*)(int, int)) api_list[0])(1, 2);
You may use GCC extensions typeof, but this method requires writing function's name (here fp) explicitely:
int result = ( (typeof(fp)*) api_list[0].func)(1, 2);
Even if you have stored somehow character string "fp" inside name member, there is no way to "connect" it with typeof, since it does not take string literals (well it takes, but not in the way you want) and in general there is no way to have it "destringized" as fp token.
Here is an illustration of above concepts:
#include <stdio.h>
typedef void (*GENERIC_FUNC_PTR)();
typedef struct function
{
GENERIC_FUNC_PTR func;
} function;
void Register(function *api_list, GENERIC_FUNC_PTR func)
{
api_list->func = func;
}
int add(int a, int b)
{
return a + b;
}
void print_message(void)
{
printf("%s\n", __func__);
}
int main(void)
{
function api_list[10];
Register(api_list, (GENERIC_FUNC_PTR) add);
Register(api_list + 1, (GENERIC_FUNC_PTR) print_message);
printf("%d\n", ( (typeof(add)*) api_list[0].func)(1, 2));
( (typeof(print_message)*) api_list[1].func)();
return 0;
}

Passing pointers as function arguments in C

I'm trying to understand the behavior of pointers in C in context of passing them as arguments to function, so I tried messing around and making the following test case:
void function1(int argument)
{
argument=4;
}
and
void function2(int* argument)
{
*argument=5;
}
if I run the following statements:
int var1;
int* var2;
function1(var1);
function1(*var2);
function2(&var1);
function2(var2);
In which cases will changes made to the variables be reflected in the calling function?
I tried running the following sample code but am not able to understand output
#include <stdio.h>
void funone(int arg)
{
arg=5;
}
void funtwo(int* arg)
{
*arg=6;
}
int main(void) {
int var1=0;
int *var2;
var2=(int *)malloc(sizeof(int));
*var2=0;
funone(var1);
printf("%d",var1);
funone(*var2);
printf("%d",*var2);
funtwo(&var1);
printf("%d",var1);
funtwo(var2);
printf("%d",*var2);
return 0;
}
the output I'm getting is
0066
what is the implication of this output?
Your code for function1 changes the value of the variable in the function only. So there are no repercussions of the change outside of the function.
Your function2 works (ie, changes the values it points to) because pointers can point to variables outside of it's scope. But your first function keeps the value inside of it's scope, and once the function returns any changes are lost.
This explanation should be present in any good tutorial about pointers.
Neither of those examples will work as you're simply setting the value of the pointer using those functions. Below you will find a version which achieves the behaviour you wish:
void function2(int* argument)
{
*argument=5;
}
The reason for the asterisk before the argument parameter is because you are dereferencing the value of the pointer (you are getting access to it) and therefore you may, at that point change its value...
I hope this helps...

Pointer to a function that takes a pointer to another function as argument

This should be a simple question, but I might not be able to word it correctly or I might be trying to defy the principles of the C language because of my lack of experience with it.
All I want to do is, given a pointer to a function, to wrap it inside another function that takes a pointer to a function as an argument, and make a pointer of the later. Better in code:
void do_nothing_1() {}
void do_nothing_2() {}
void wrapper(void(*f)()) { f(); }
int main() {
// the following will call the function
// but i just want a pointer of whats being called
funcion_pointer_1 = wrapper(do_nothing_1);
funcion_pointer_2 = wrapper(do_nothing_2);
return 0;
}
I apologize beforehand if the question doesn't make any sense, please help me clarify it rather than simply downvote it.
Edit: Given the apparent difficulty to obtain the results desired because of the obscurity of the requirements, I will be a little more specific on what I am looking for.
Inside a struct, I have a pointer to a function:
struct my_struct {
int (* run)(void);
}
What I want to do is to modify that function and that's why I use the wrapper. So, for example, if foo returns void change that to int. Also, run some code before executing foo:
int wrapper(void (*foo)()) {
// exec some stuff here
foo();
return 0;
}
Ultimately, what I want is that when I execute the function corresponding to the *run pointer from my structure, execute some stuff before doing run() and change the return type.
When struggling with the correct syntax, it is helpful to use typedefs to make things clearer. Not just for yourself as you write the code, but for anyone who needs to maintain it, or just try to figure out what it's doing.
You want a function pointer to a function that takes another function pointer as an argument. Start with the argument, a function without parameters and no return value:
typedef void (*void_handler_t)( void);
And now the wrapper function pointer, one that takes a function pointer parameter and has no return value:
typedef void (*wrapper_handler_t)( void_handler void_fn);
And the code:
void foo( void) {}
void wrapper( void_handler_t wrapped_fn)
{
wrapped_fn();
}
int main( int argc, char *argv[])
{
wrapper_handler_t function_pointer;
function_pointer = &wrapper;
function_pointer( &foo);
return 0;
}

In C: sending func pointers, calling the func with it, playing with EIP, jmp_buf and longjmp

I need to make sure i understand some basic stuff first:
how do i pass function A as a parameter to function B?
how do i call function A from inside B ?
Now for the big whammy:
I'm trying to do something along the lines of this:
jmp_buf buf;
buf.__jmpbuf[JB_PC] = functionA;
longjmp(buf,10);
Meaning that I want to use longjmp in order to go to a function. How should I do it?
You need to use a pointer to a function. The syntax for declaring a function pointer is:
rettype (*)(paramtype1,paramtype2,...,paramtypeN)
So, for example, we might have the following code:
char functionA(int x)
{
printf("%d\n",x):
return 'a';
}
char functionB(char (*f)(int), int val)
{
return f(val); // invokes the function pointer
}
int main(int argc, char* argv[])
{
char result = functionB(&functionA,3); // prints "3"
printf("%c\n",result); // prints 'a'
return 0;
}
Also, a side note, that while &functionA takes the address of functionA, it is actually not necessary to use the ampersand there... I personally do it, since I think it makes it more clear that it is a function pointer. You invoke a function pointer using the same syntax that you would when invoking a function.
As for using jump buffers, I believe what you are doing is not something that can be relied upon. If you want to create a jump buffer and invoke setjmp before invoking some function, then later invoke longjmp so that you return to immediately prior to the call, then that is well-defined. The actual definition and structure of jmp_buf, though, is implementation-specific. There are certain requirements that it has to meet (e.g. it has to be an array type, because setjmp has to be able to take it by value and yet modify it), but other than that, the specification for setjmp.h does not define the structure of jmp_buf. So, anything that attempts to manipulate jmp_buf directly is going to be specific to a particular platform.
Passing functionA as a parameter to functionB:
typedef void function_type(void);
void functionA(void)
{
printf("This is function A\n");
}
int main(int argc, char **argv)
{
functionB(&functionA);
return (0);
}
Calling function A from function B:
void functionB(function_type *func)
{
func();
}
Using longjmp() to go to a function. The best answer is "Don't do this" - there's almost always a better way to achieve the same aim. Can you explain the situation where you need this?

Resources