Call flow for the code - C - c

I am looking into some C code for a microcontroller. I understand most of the code however this piece of the code is puzzling me.
I am also including relevant definitions for used data types. I have substituted function and variable names for the ease sake.
#define COUNT (2)
typedef void(*some_type)(void *p);
some_type some_arr[COUNT] = {NULL, };
void init(void)
{
first_function(&second_function);
}
void first_function(some_type cb)
{
if(some_arr_count < COUNT)
{
some_arr[some_arr_count++] = cb;
}
}
void second_function(void *p)
{
another_type *req;
req = (another_type *)p;
//some other code goes here
}
1.What does this typedef means?
typedef void(*some_type)(void *p);
init() function gets called only once and it has only one line of code.
2.What does this line do?
first_function(&second_function);
I searched for the term second_function in the entire project code and it this the only place it appears besides function definition.
3.So how does second_function get called?

The following typedef
typedef void(*some_type)(void *p);
will define some_type as a pointer to function of type void ()(void *).
The following statement
first_function(&second_function);
is a function call, &second_function, which is the address of second_function , is the argument to first_function().
The function second_function could be called like this
some_arr[some_arr_count](p);
some_arr[some_arr_count] is a function pointer to second_function, which is assigned in first_function, and p is the argument of second_function, which is a pointer to void.

Firstly, as suggested in the comments you should go read about function pointers. I got this (How do function pointers in C work?) from a Google search.
The above link should help to explain answers to question 1 and 2. For question 3, it is likely that the micro-controller has some built-in mechanism or library function which calls all the function call-backs in some_arr[COUNT], something like the following might work (untested):
for (int i = 0; i < COUNT; ++i)
{
if (some_arr[i] == NULL) break;
(*some_arr[i])(&something_useful);
}
Where something_useful would be some sort of data that the call-back function could use.
If you are able to search the library code for uses of some_arr you might find code to call the second_function (although it will no longer be called second_function).

Related

Python-like function decorators in C

I'm trying to implement a Python-like function decorator in C using function pointers but I'm getting weird segmentation fault error.
Idea is that we have a decorator function which has inner function wrapper. Decorator then takes some_function as an argument, puts it inside the wrapper along with additional code and returns the wrapper function.
Very simple function decorator in Python:
def decorator(f):
def wrapper():
#do something before
f()
#do something after
return wrapper
def some_func():
print('Hello')
some_func = decorator(some_func)
I know that Python, unlike C, treats functions as first class objects but I'm wondering if the same sort of functionality can be emulated in C by using function pointers.
I tried this
void* do_twice(void (*func)())
{
auto void wrapper()
{
func();
func();
}
return &wrapper;
}
void some_func()
{ printf("Hello\n"); }
int main()
{
void (*fun_ptr)() = &some_func;
fun_ptr = decorator(fun_ptr);
fun_ptr();
return 0;
}
Output
Hello
Segmentation fault
Now here is the funny bit. If I declare a variable inside wrapper like this:
auto void wrapper()
{
int blah=5;
func();
func();
}
Then segmentation fault is fixed. Can someone explain why is this so? Apparently I'm doing something wrong with the pointers and code is very unstable - seemingly unrelated additions to the main function will cause segmentation fault to pop again.
Do you allow me to have an excursion to C++? In this language, there are functor objects, these are kind of structs that can be called like a function:
struct Wrapper
{
/* this is what allows the struct to be called like a function: */
void operator()(/* can define arbitrary parameters here */)
{ /* some implementation */ }
};
In other words, this would allow you to write code like:
Wrapper w; // actually, C++ does more here than C, but that's out of
// scope of this question...
w(); // possible due to the operator() defined above
OK, now let's extend that a bit:
struct Wrapper
{
void(*m_f)(void); /* !!! */
void operator()(void) /* don't want any parameters... */
{
printf("before\n");
m_f();
printf("after\n");
}
};
Don't want to go any deeper, a C++ developer would now deal with accessibility (such that the member m_f can only be used inside the class) and would provide a so-called constructor (for initialising m_f member appropriately). With all that, the final C++ code using the wrapper class might look like:
Wrapper decorate(void(*f)(void))
{
return Wrapper(f); // the fore-mentioned constructor gets called
}
void test(void) { /* do something */ }
void demo(void)
{
Wrapper w = decorate(&test);
w();
}
Why that excursion? Well, have a close look at one specific line:
void(*m_f)(void);
Yes, there is a member variable! Python actually does something similar internally.
The 'problem' with C is that you cannot define your own function call operators. There's only the native one. So the big question is: Where to store the function pointer?
You could have a struct, storing the function pointer (analogously to the C++ solution), and pass that one to your own function emulating the function call operator. Actually, the C++ solution doesn't do anything else either, solely that all this is hidden behind syntactic sugar!
An equivalent C solution might look like this:
struct Wrapper
{
void(*m_f)(void);
};
void executeDecorated(Wrapper w)
{
printf("before\n");
w.m_f();
printf("after\n");
}
void demo(void)
{
Wrapper w = { &someFunction };
executeDecorated(w);
/* do whatever else ... */
executeDecorated(w);
}
This is probably the closest you can get in C (apart from that you might perhaps find better names).
If having a separate struct to store a function pointer brings you sufficient benefit or if you just want to pass the function pointer directly (executeDecorated(&someFunction), assuming the function was adjusted appropriately) is up to you to decide...

Returning directly to main from a function call of a function call

just as a disclaimer this question has to do with a particular assignment I have an I am not asking for anyone to do my homework for me.
So basically I am supposed to implement a way to return directly to main from a function call of a function call.
Part of the stipulations are that we cannot use an assembly language instructions, gcc's asm(), or gcc built ins. After doing a lot of research on this on google I couldn't really find any examples to look at or even the source code for setjmp/longjmp (the purpose of this assignment is to copy those functionalities). I've asked some more older CS students for advice and most couldn't help or told me they are pretty sure it is not possible with the stipulations given. Any advice or pointers (haha) will be appreciated. Even a nudge in the right direction or confirmation that the assignment is not as complicated as I think will be greatly appreciated!
So far my best attempt:
-Use a setjmp function to store the address of where we left off in main (so something like x = foo1(); and pass x into setjmp(x)) and then have foo2 call my longjmp function where in longjmp I'll have the function set a pointer (*p) to my argument and then (*p-1) = address of x in main.
This didn't work but I thought it was the right idea trying change the return address in the call stack since if I understood it correctly, the arguments of the function are directly on top of the return address in the stack.
Here is the code I wrote:
int setjmp(int v);
int longjmp(int v);
int fun1(void);
int fun2(void);
int *add; //using global, not sure if best idea
int main(void)
{
int x = setjmp(x);
foo1();
return 0;
}
int setjmp(int v)
{
add = &v; //used a global variable
return 0;
}
int longjmp(int v)
{
int *p; //pointer
p = &v; //save argument address
*(p-1) = *add; //return address = address in main
return 1;
}
int foo1(void)
{
printf("hi1");
foo2();
printf("hi2");
return 0;
}
int foo2(void)
{
int a;
longjmp(a);
return 0;
}//output SHOULD be "hi1"
//output is currently "hi1" "hi2"
for what it's worth every line I have not commented was given as a skeleton and I cannot change it.
Excuse me in advance if something is off, I am quite new to C. Thank you.
"So basically I am supposed to implement a way to return directly to main from a function call of a function call. "
This requirement is nonsense. Any attempt to sate that requirement will result in trash code. Training to write things like this is directly harmful practice. This is a very bad assignment and your teacher should be ashamed for teaching you bad practice with no disclaimer. There is also never a reason to do things like this in real-world programs.
You can't implement the setjmp/longjmp functions in pure C, you would have to use inline assembler. They save the program counter and other such things needed by the specific system. They also meddle with the stack pointer, which is one reason they are dangerous.
So the only way to do this in standard C is to use the standard library functions setjmp/longjmp from setjmp.h. These are widely considered very bad and dangerous since they lead to unreadable spaghetti programming and many forms of undefined behavior. One example of undefined behavior from the C standard:
After a longjmp, there is an attempt to access the value of an object of automatic
storage duration that does not have volatile-qualified type, local to the function
containing the invocation of the corresponding setjmp macro, that was changed
between the setjmp invocation and longjmp call
Don't use these functions ever.
That being said, this is how you write horrible, dangerous programs:
// BAD! NEVER WRITE SPAGHETTI CODE LIKE THIS!
#include <stdio.h>
#include <setjmp.h>
#include <stdbool.h>
static jmp_buf jmp_main;
void func2 (bool one_more_time)
{
puts(__func__);
if(one_more_time)
{
longjmp(jmp_main, !one_more_time);
}
printf("end of "); puts(__func__);
}
void func1 (bool one_more_time)
{
puts(__func__);
func2(one_more_time);
printf("end of "); puts(__func__);
}
int main (void)
{
bool one_more_time = (bool)!setjmp(jmp_main);
puts(__func__);
func1(one_more_time);
printf("end of "); puts(__func__);
}
Output:
main
func1
func2
main
func1
func2
end of func2
end of func1
end of main
I don't think problem is that complicated. You should be calling another function with a condition on returning value such that if it is certain value (say 0) then return otherwise continue on the function.
So you can just replace foo2(); with :
if (foo2() == 0) return 0;
Now in foo2() function return 0; whenever you wish to return to main function call of foo1() otherwise continue with foo1() statements. You need not use setjmp here.
You may also find this article helpful: Tread programming examples

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;
}

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;
}

Passing function pointers & int references to another function

Just started working on a c project. Need help with passing function pointers/macro functions/etc. I'm a php & python OO guy, but new to c. I tried to generalize the example for this post. I have a main.c with a lib for the Axon microcontroller I'm working with. Works like a charm with everything in main.c. I need to move some of the functionality out of main to more organized lib files as my code grows. The base microcontroller lib creates a macro function that allows me to send data to the microcontroller to make a servo move left or right. I now need to create a servo specific file (HS-422.c) that will will allow me to pass references/pointers(?) to a generic function that will execute for each servo to ease on code duplication.
Keep in mind I'm only focused on passing macros/functions/variable references to other functions and have them called / set. The other basics of c I understand. I must have tried a 100 different ways to make this work today with no luck. So just wrote a simplified version hoping you might get an idea of what I'm attempting.
Thank you for your help!
/*
* main.h
* I'm trying to make a pointer or reference to the macro.
* The original file had:
* #define servo1(position) servo(PORTE,2,position);
*/
// servo is a macro defined in another microcontroller file
#define (void)(*servo1)(position) servo(PORTE,2,position);
#define (void)(*servo2)(position) servo(PORTE,3,position);
/* main.c */
// init main functions
void servo_scan(void);
// init vars
int servo1_location = 0;
int servo2_location = 0;
int main(void)
{
for(;;)
{
servo_turn();
}
}
// get the servos to turn
void servo_turn(void)
{
turn_servo( *servo1, &servo1_location, 200);
turn_servo( *servo2, &servo2_location, 950);
}
/* HS-422.c */
void turn_servo(void (*servo)(int position), int &currentLocation, int newLocation)
{
// turning
for(uint16_t i=&currentLocation; i<newLocation; i=i+10)
{
// turn servo
// hoping the specifc passed servo# pointer gets called
*servo(i);
// set value by reference to origional servo#_location var. making sure.
&currentLocation = i;
// pause
delay_ms(20);
}
}
It's not really clear to me exactly what you're trying to achieve, but what is clear is that you don't really understand the concept of pointers/references in C - so I'll try to clarify, and hopefully that will help you implement what you need.
Firstly, there is no such thing as a "reference" in C. The only alternative to passing by value is to pass a pointer. A pointer is basically just a memory address, and you can get a pointer (memory address) to a variable using the & (address of) operator. When passing a pointer variable to a function, you do something like the following:
Given a function which takes a pointer:
int foo(int* pointer);
You would pass the memory address of an int variable to this function like so:
int x = 10;
foo(&x);
So right off the bat, you can see that your function definition above is wrong:
void turn_servo(void (*servo)(int position), int &currentLocation, int newLocation);
This is simply a syntax error. It will not compile because of the int &currentLocation. The & operator is used to take the address of a variable. It can't be used in a function parameter. If you want a "reference" to currentLocation, you need to pass in a pointer, so your function parameters should be written as:
void turn_servo(void (*servo)(int position), int* currentLocation, int newLocation);
Secondly, when you want to modify the value pointed to by the currentLocation pointer, you need to use the * operator to dereference the pointer. So, the line where you set currentLocation is not correct. What you want to say is:
// set value by to origional servo#_location var. making sure.
*currentLocation = i;
And of course, the line:
for(uint16_t i=&currentLocation; i<newLocation; i=i+10)
should be:
for(uint16_t i= *currentLocation; i<newLocation; i=i+10)
Note that in your original code you use the & operator in both cases, which takes the address of a variable. Since currentLocation is already a memory address, this would result in taking the address of an address, also known as a pointer-to-a-pointer, which is certainly not what you want here.
Finally, the phrase "pointer or reference to the macro" is completely nonsensical. A macro is not a function. It is more like a meta-function: essentially it is a template used by the C preprocessor to generate further source code. The C preprocessor is invoked before the compilation phase, and basically acts as a find/replace mechanism in the source code. You can't have a pointer to a macro, because for all intents and purposes macros don't even exist in the compilation phase. They are only meaningful to the preprocessor.
There may be more here, but ultimately you seem to have a fundamental misunderstanding of pointers (as well as macros) in C, and short of providing a complete tutorial, the best I can do is point out the syntax problems. I highly recommend you read a good introductory book to C, which will certainly go over pointers, macros, and functions.
I have picked the main point of your code and have this code below.
You may want to modify your #define in your original code.
Please see the code below: (you can also run this)
void myFunc(int pos);
void myFunc2(int pos);
int main (int argc, const char * argv[]) {
typedef void (*pFunc)(int);
pFunc pfArr[2];
pfArr[0] = &myFunc;
pfArr[1] = &myFunc2;
int x = 3;
int newLoc = 4;
turn_servo(pfArr[1], x, newLoc);
turn_servo(pfArr[0], x, newLoc);
return 0;
}
void turn_servo(void (*servo)(int position), int currentLocation, int newLocation)
{
printf("\nturn_servo starts");
printf("\nturn_servo currentLocation: %d", currentLocation);
printf("\nturn_servo newLocation: %d", newLocation);
servo(1);
}
void myFunc(int pos)
{
printf("\nmyFunc starts");
printf("\nmyFunc pos: %d", pos);
}
void myFunc2(int pos)
{
printf("\nmyFunc2 starts");
printf("\nmyFunc2 pos: %d", pos);
}
Your turn_servo() function will now accept two functions as parameter (either myFunc() or myFunc2()).
Just get the main point of this code and apply it. Hope this will help.

Resources