Passign code as a function parameter instead of declaring a callback - c

I think that some newer languages like JS can do this natively, but I forget the term for it (make a "temporary" function in-line just to pass as a callback)
What I want to do is ...
I'm writing unit tests where I set up expected input & output messages at compile time. Later at run time, I want to do some checks when each output is received or input has been processed, so I added a parameter for a callback function.
That's working fine and I could leave it & move on, but ... I am just curious ...
sometimes a function is overkill and I just need a single comparison; sometime a small block of code would do. Perhaps I could just evaluate these to a zero/non-zero value at run time? But how to pass as a parameter?
At the moment my function has the following signature
void AddExpectedCommand(E_peripheralType peripheral,
communicationBlock_t commandBlock,
errorMessage_t errorMessage,
void *(*DoRunTimeChecks)(E_boolean));
where the final parameter is pointer to a callback function returning boolean.
Is there any way that I could pass a code expression as a parameter instead?
Or does a function seem "cleaner"?
Thanks in advance for any help ...
Update: oops, I got my declaration wrong. I want to pass a pointer so a function which has no parameters and returns an e_Boolean ... how do I do that?

With C++11 you can do the following:
Function taking a function that returns a bool:
void f(function<bool()>);
Call it with a lambda capturing a local variable:
int x = ...;
f([&x]() { return (x > 2); });
Or call it with some function g that returns a bool:
bool g();
f(g);
Or bind some function h that takes an int and returns a bool:
bool h(int x);
f(bind(h, 2)); // ie creates a nullary function from h(2)

What you're looking for is called a "lambda expression" or "anonymous function." And they don't exist in C (but do in C++ with certain qualifications).

Related

C: Declare and execute function in one line

I can do the following in GCC:
#define INIT_MODULE(name) \
({ extern int name(void); name(); })
int main(void) {
return INIT_MODULE(x);
}
Here, the function (expanded from name) is created, executed, and returned via a statement expression (GCC extension). This is a minimal repo: I am actually doing some __asm__ magic to make the name function, hence the macro.
I would like to have this be a one-liner, and not call another macro to create the name function. In my use case, the caller will only call INIT_MODULE once, and does not/should not know the name of the underlying function it is calling.
Basically, I need a way to declare, run, and return the value of a function, all in one line (without using GCC extensions!).
What I DONT want:
// ...
DECL_MODULE(x);
int main(void) {
return INIT_MODULE(x);
}
Any thoughts?
I think there's more to what you want than to simply declare, run and return the function - otherwise you could do it right away in the same manner you already achieved.
The problem that I see is that you want the function to be visible externally, as if it was declared outside of the scope of the caller. And that's clearly not possible, since #define just replaces the content of the macro (it can't move it in another point of the code).
Actually, you could use low-level goto and some arithmetics, but I'd rather not recommend you that path.

How to call a single argument from a function with multiple argument in C?

Say you have a several function like this:
void Inventory(int index, char input[], int qty)
void AddItem(){
int index = Inventory(index);
if (int i = 0; i < index; i++){
...
}
}
But it gave me an error 'A value of type "Void" cannot be used to initialize an entity of type "int"'
Can someone explain to me in detail since im new to programming too.
You're trying to initialize index as an int whose value is returned by calling Inventory(index). But the Inventory function you provided has a return type of void, not the expected int, so there's no way to get that value.
Also, your call to Inventory is missing an argument to the chat input[] and int qty parameters. Additionally, index is uninitialized at the time that you're trying to use it (within the definition of index).
The function Inventory does not return anything (which is void) and you are trying to affect 'nothing' to a variable of type int. That's why the compiler is complaining.
The solution is to have your Inventory function return an int value instead of void.
First of all, your question and code snippet that you have provided are misleading.
Secondly, You are getting this error because the return type of function Inventory is Void, which means it returns nothing. And you are trying to assign nothing to variable index, which is of type int.
And, if you are trying to call multi-argument function without having to pass all arguments, make rest of the argument optional.
void foo(/.../) means that the function foo does not return anything. So you cant assign nothing to something.
In C you need to pass all the parameters. In other languages (like C++) some parameters might have default values and you do not have to pass them when call the function. But it is not possible in the C language and you need to pass all the parameters (arguments)

How to access value passed into void tmin(void) function and then alter it?

I am working on an assignment. My teacher has given me this function
void tmin(void){
return 2;
}
I need to take whatever value is passed into this function, manipulate it, and return it. Where I am stuck is the tmin(void) part. How do I work on the value that is passed in if it just says void? Is there a way to assign it to a new variable?
A function void f(void) { ... } does not accept a anything to pass into the function, nor does it return anything. You need to change the signature of the function (return type and parameters and its types) and its body according to the task your teacher gave to you.

Why is this function seen as a delegate?

In an attempt to wrap a C function taking callbacks, I encountered the problem of member functions being seen as delegates. The C function wouldn't take delegates, so I settled on something else instead:
extern(C) void onMouse(void delegate(int, int, int) nothrow callback)
{
glfwSetMouseButtonCallback(handle,
function void (GLFWwindow* h, int button, int action, int mods) nothrow
{
callback(button, action, mods);
}
);
}
As you can see, I'm passing to the callback setting function a function literal calling a delegate (which would be the member function I pass here).
However, it doesn't end up as I expect:
Error: function pointer glfwSetMouseButtonCallback (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int, int) nothrow) is not callable using argument types (GLFWwindow*, void delegate(GLFWwindow* h, int button, int action, int mods) nothrow #system)
In the error, it shows the second parameter as being as the type void delegate.
So. My question is: why does this happen? As you can clearly see, it says function void in the code.
NOTE: I've seen this: Pass delegates to external C functions in D.
The solution is apparently a hack. But I will try it if I cannot find a workaround on the internet.
Even though you declare it as function, it cannot be. It relies on the parameter you pass to onMouse. That parameter is a local variable, and accessing them in a function body makes them a delegate. All you can do is change the parameter to function and pass it with &callback (you'd need to add GLFWwindow as parameter then).
Alternatively, you can create a global list in which this callback puts events which you can then process in your main loop.

Calling function with variable arguments dynamically

Is there a possibility to call function with variable arguments from the C code dynamically?
For example I have text file which contains data (written using this scheme: function_name arguments) for example:
func1 1 2 3
func2 1
func3
My program written in C is parsing this file and looks in a populated array (which holds function name in string and target native function pointer) for function with given name by comparing the string and calls a pointer of this function with arguments from the text file. For example functions like that:
void func1(int a, int b, int c) { }
void func2(int a, int b) { }
void func3() { }
The problem is that even if I know the number of arguments, I don't know how to write in C function pointer call with dynamic number of arguments. Is there a possibility to populate va_list (I know that this is NOT a container or a typical array!) then pass to the native function or any other way to do this? The only way which came into my mind is populating dynarec block with x86 code for calling native function with variable arguments, but it's not a clean solution. Is such thing even possible in plain C?
If it is hard to understand just write and I'll try to explain better. And if you want to write "use va_list" - then read carefully my post once again.
Thanks in advance.
I'm self answering, because this will be a solution for other people. If you want to call functions with variable arguments dynamically without writing direct machine code just use avcall library from FFCALL. Quick reference guide of avcall library can be found here. It's a crossplatform library that makes this possible. For example to call function named func1 with return type void which takes three arguments and all of them are of type int just do this:
#include <avcall.h>
int a = 1, b = 2, c = 3;
av_alist alist;
av_start_void(alist,&func1);
av_int(alist,a);
av_int(alist,b);
av_int(alist,c);
av_call(alist);
You can of course use this for functions which returns value or takes arguments of different type, for more just look at avcall library manual page. :)
I like your way of thinking, because obviously, you are a true hacker, but...
do not try to do it like this.
The proper way of doing this is to go alter these functions so that each one of them accepts an array of int instead of individual int parameters. But I suppose that if you had the freedom to change them, you would have done it already and you would not be asking.
The next best way of doing it is to write a number of functions, conv1(), conv2(), conv3() etc, each accepting an array of int, and a pointer to a function which accepts individual int parameters. So, convN() accepts an array of N integers, and a pointer to a function which accepts N individual int parameters. It reads each int from the array and passes it to the function as a parameter. It can do this, because it has been specifically written to work with a function of precisely that number of parameters. Then, in your table with function names and pointers to functions, add a pointer to the right convN() function, depending on the number of parameters that the target function expects.
Don't hack it.

Resources