Does 'void (*)(int)' the same with 'void (^)(int)'? - c++

Today, I'm working on a callback pass from C++ to Objective-c method.
Finally, I worked it out, but a few code confuse me.
In Objective-c, people ordinary use block to implement a callback, a block declare looks like this:
returnType (^blockName)(parameterTypes)
I also learned about C++ callback, a same type callback defined like this:
returnType (*funcName)(parameterTypes)
When I passed a callback from C++ to Objective-c, compiler warning me:
"Cannot initialize a parameter of type 'void (^)(int)' with an rvalue of type 'void (*)(int)"
Finally, I changed ^ to *, it works. I wondering to know, what's the difference between ^ and * in definition, is that have the same behavior?

This is a block:
returnType (^blockName)(parameterTypes)
This is a function pointer:
returnType (*funcName)(parameterTypes)
They aren't compatible.

Standard C and C++ do not have callable blocks. Apparently, however, some compilers for those languages do implement the feature as an extension. Some of the docs I see suggest that it's an Apple extension to Objective C, too, but inasmuch as Objective C is little used outside the Apple world, that may be a distinction without a difference.
In whatever language, if you implement a callback as a function, then you must present that callback to the intended caller via a function pointer, and the caller must be prepared to accept it in that form. On the other hand, if you implement a callback as a block then you must present it to the caller via a block pointer, and the caller must be prepared to accept that form. The two are not interchangeable, and they have different syntaxes, which you have presented. It would be possible to design a mechanism that could accept both forms, however, via separate parameters or altogether separate registration functions.

Objective-C blocks (^) are incompatible with function pointers (*).
Compared to function pointers, they have the benefit of being able to capture values and variables from the surrounding context (they are closures).
It's easy enough to write a wrapper that calls a function pointer from a block:
typedef int (*funptr)(int);
typedef int (^funblock)(int);
int use_block_callback(int y, funblock fb)
{
return fb(y);
}
int use_funptr_callback(int y, funptr f)
{
return use_block_callback(y, ^ int (int x) { return f(x); });
}
int add_one(int x) { return x + 1; }
int foo(int x)
{
return use_funptr_callback(23, add_one);
}
// Or
int (*some_pointer)(int) = add_one;
int (^some_block)(int) = ^ int (int x) { return some_pointer(x); }
("Programming with Objective-C" about blocks.)

Related

Typecast callback functions

Can I typecast callback functions?
I like to write a library that registers and calls certain callback functions.
int MyCaller::add_callback_function(int (*callback_function)(), byte behaviour) {
this->callback = callback_function;
}
void MyCaller::run() {
int result = this->callback();
}
// ....
int get_number() { return 42; }
MyCaller my_caller;
my_caller.add_callback_function(get_number, 0);
my_caller.run();
However, I would also like to support callback_functions that output a boolean.
bool get_bool() { return true; }
MyCaller my_caller;
my_caller.add_callback_function(get_number, 0);
my_caller.run();
If I try this, my code seems to run fine, but gcc will give a warning: invalid conversion from 'bool (*)()' to 'int (*)()' [-fpermissive].
To avoid this warning, I overloaded my add_callback_function with a slightly different signature:
void MyCaller::add_callback_function(bool (*callback_function)(), byte behaviour) {
// ...
}
However, I'm lost from this point onward. I expected that I could cast any boolean to an integer, and call the original method:
void MyCaller::add_callback_function(bool (*callback_function)(), byte behaviour) {
this->add_callback_function(static_cast<int (*)()>(callback_function), byte behaviour);
}
However, this gives an error: invalid static_cast from type 'bool (*)()' to type 'int (*)()'.
So I seem to be doing something wrong.
Is there a clean way to do this?
For bonus points: My code stores an array of callback functions, and I like to be able to optionally add a context parameter (to e.g. allow calling methods besides functions). I plan to store all these callbacks (with different signatures) as a int (*)(), and typecast them to their proper form before calling them. Would that be the best way, or are there other (perhaps better) ways to handle this?
The alternative I can think of is to only support one very specific callback signature, but that forces users to write wrappers. I like to put that burden on the library.
You can cast one function pointer type to another, but you can only call it if you cast it to the real function pointer type. You can only store them as the wrong signature.
Calling them any other way results in undefined behavior. The most likely symptom will depend on your platforms current calling convention. But really, just don't do it.
The easiest correct solution is to store a
std::function<int()>
this isn't a function pointer, but can store any callback (including a function pointer) that can be copied, moved, and invoked with zero arguments and returns something compatible with an int (which a bool qualifies as).
std::function can also store objects with state. For example:
struct Foo {
int count = 0;
int callback(){ return ++count; }
};
Foo foo;
std::function<int()> f = [&foo]{ return foo.callback(); };
naturally you become responsible for lifetime. Look up "C++ lambdas" to understand the above syntax.

Function call syntax through a pointer dereference

Consider the code
int add(int a, int b)
{
return a + b;
}
int main()
{
std::cout << (*add)(3, 2);
}
What is the point of dereferencing the function pointer ???
I can't think of such a use case where it would give an advantage ...
Why this function call syntax exists in C++ ?
This syntax exists because C had it, and C++ syntax was originally based on C.
There is no difference in the code behaviour of f(args) and (*f)(args).
I can't be sure if I am right, but here is a possible explanation:
Every function in c and as well as in c++ is a potential variable.
Possible declaration of function is:
int (*MyFunction)(int, double);
In this case- Variable name: MyFunction | Type: function that returns int with int, double parameters.
So, even when you declare function, you actually declare variable with a "function" type. In this case, it is make sense why can you use, in your case (*add)(3, 2) for function calling (or using a variable).
It may by more clearly for you to have a look on lambda expressions, which can make a function implementation, and then let you use it like a local function variable:
int(*MyFunction)(int, double) = [](int a, double b) -> int {
return (int)((a + b) * 10);
};
Here we declare on function type variable, and implement a function for it with a lambda expression. Now we can use it in two forms:
MyFunction(1, 2.5); // Like a regular function
(*MyFunction)(1, 2.5); // As a function type variable
Again, it is the most sense explanation that I could think of. I don't sure if it is a right/best/fully explanation, but I hope it gave you a new perspective of functions.

If void() does not return a value, why do we use it?

void f() means that f returns nothing. If void returns nothing, then why we use it? What is the main purpose of void?
When C was invented the convention was that, if you didn't specify the return type, the compiler automatically inferred that you wanted to return an int (and the same holds for parameters).
But often you write functions that do stuff and don't need to return anything (think e.g. about a function that just prints something on the screen); for this reason, it was decided that, to specify that you don't want to return anything at all, you have to use the void keyword as "return type".
Keep in mind that void serves also other purposes; in particular:
if you specify it as the list of parameters to a functions, it means that the function takes no parameters; this was needed in C, because a function declaration without parameters meant to the compiler that the parameter list was simply left unspecified. In C++ this is no longer needed, since an empty parameters list means that no parameter is allowed for the function;
void also has an important role in pointers; void * (and its variations) means "pointer to something left unspecified". This is useful if you have to write functions that must store/pass pointers around without actually using them (only at the end, to actually use the pointer, a cast to the appropriate type is needed).
also, a cast to (void) is often used to mark a value as deliberately unused, suppressing compiler warnings.
int somefunction(int a, int b, int c)
{
(void)c; // c is reserved for future usage, kill the "unused parameter" warning
return a+b;
}
This question has to do with the history of the language: C++ borrowed from C, and C used to implicitly type everything untyped as int (as it turned out, it was a horrible idea). This included functions that were intended as procedures (recall that the difference between functions and procedures is that function invocations are expressions, while procedure invocations are statements). If I recall it correctly from reading the early C books, programmers used to patch this shortcoming with a #define:
#define void int
This convention has later been adopted in the C standard, and the void keyword has been introduced to denote functions that are intended as procedures. This was very helpful, because the compiler could now check if your code is using a return value from a function that wasn't intended to return anything, and to warn you about functions that should return but let the control run off the end instead.
In imperative programming languages such as C, C++, Java, etc., functions and methods of type void are used for their side effects. They do not produce a meaningful value to return, but they influence the program state in one of many possible ways. E.g., the exit function in C returns no value, but it has the side effect of aborting the application. Another example, a C++ class may have a void method that changes the value of its instance variables.
void() means return nothing.
void doesn't mean nothing. void is a type to represent nothing. That is a subtle difference : the representation is still required, even though it represents nothing.
This type is used as function's return type which returns nothing. This is also used to represent generic data, when it is used as void*. So it sounds amusing that while void represents nothing, void* represents everything!
Because sometimes you dont need a return value. That's why we use it.
If you didn't have void, how would you tell the compiler that a function doesn't return a value?
Cause consider some situations where you may have to do some calculation on global variables and put results in global variable or you want to print something depending on arguments , etc.. In these situations you can use the method which dont return value.. i.e.. void
Here's an example function:
struct SVeryBigStruct
{
// a lot of data here
};
SVeryBigStruct foo()
{
SVeryBigStruct bar;
// calculate something here
return bar;
}
And now here's another function:
void foo2(SVeryBigStruct& bar) // or SVeryBigStruct* pBar
{
bar.member1 = ...
bar.member2 = ...
}
The second function is faster, it doesn't have to copy whole struct.
probably to tell the compiler " you dont need to push and pop all cpu-registers!"
Sometimes it can be used to print something, rather than to return it. See http://en.wikipedia.org/wiki/Mutator_method#C_example for examples
Functions are not required to return a value. To tell the compiler that a function does not return a value, a return type of void is used.

How can I define a function pointer that takes the same arguments and return value as a given function?

For example, I have a function foo:
int foo(int a, int b)
{
return a + b;
}
I can define a function pointer:
int (*pfoo)(int, int);
But how can I do this dynamically in program?
I want a function that takes a function as a parameter, and return a function pointer that takes the same arguments and return value as a given function.
Then I can use it like this:
void* pfoo = getFuncPtrFromFunc(foo);
Which does what the code above did.
Is this possible?
You cannot do this at run-time (i.e. dynamically); remember that all types (and function pointers are types) are statically determined at compile-time.
Imagine if you could do this, and you somehow obtained a function-pointer whose type was variable (i.e. it could point to a float (*)(int,int) or a char (*)(float)). How would you ever be able to call that and provide a meaningful list of arguments?
You can, however, get this information at compile-time; one way is to use the Boost TypeTraits library.
c++ is a static typed language, and doesn't allow to do what you want.

What does "typedef void (*Something)()" mean

I am trying to understand what this means, the code I am looking at has
in .h
typedef void (*MCB)();
static MCB m_process;
in .C
MCB Modes::m_process = NULL;
And sometimes when I do
m_process();
I get segmentations fault, it's probably because the memory was freed, how can I debug when it gets freed?
It defines a pointer-to-function type. The functions return void, and the argument list is unspecified because the question is (currently, but possibly erroneously) tagged C; if it were tagged C++, then the function would take no arguments at all. To make it a function that takes no arguments (in C), you'd use:
typedef void (*MCB)(void);
This is one of the areas where there is a significant difference between C, which does not - yet - require all functions to be prototyped before being defined or used, and C++, which does.
It introduces a function pointer type, pointing to a function returning nothing (void), not taking any parameters and naming the new type MCB.
Let's take an example
typedef void (*pt2fn)(int);
Here, we are defining a type pt2fn. Variables of this type point to functions, that take an integer as argument and does not return any value.
pt2fn kk;
Here, kk is a variable of type pt2fn, which can point to any function that takes in an integer as input and does not return any value.
Reference:https://cs.nyu.edu/courses/spring12/CSCI-GA.3033-014/Assignment1/function_pointers.html
The typedef defines MCB as the type of a pointer to a function that takes no arguments, and returns void.
Note that MCB Modes::m_process = NULL; is C++, not C. Also, in C, the typedef should really be typedef void (*MCB)(void);.
I'm not sure what you mean by "the memory was freed". You have a static pointer to a function; a function cannot be freed. At most, your pointer has been reset somewhere. Just debug with a memory watch on m_process.
It's a function pointer. You get a SEGMENTATION FAULT because you are trying to make a call to a function which address is invalid (NULL).
According to your specific sample, the function should return no value (void) and should receive no parameters ().
This should work:
void a()
{
printf("Hello!");
}
int main(int arcg, char** argv)
{
m_process = a;
m_process(); /* indirect call to "a" function, */
// Hello!
}
Function pointers are commonly used for some form of event handling in C. It's not its only use though...