Function Pointer Initialization in C/C++ [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
As I was going through a ESP IDF's documentation; I saw that a function pointer was initialized in a certain way that does not make sense to me.
typedef void *app_driver_handle_t;
app_driver_handle_t app_driver_light_init();
app_driver_handle_t app_driver_button_init();
Etc.
I thought that in order to initialize a function pointer, you must do it the following way:
app_driver_handle_t = app_driver_button_init();
Sorry for my beginner level questions.
It would do wonders if someone could explain this.
Thanks

Let's break down the code you're looking at.
typedef void *app_driver_handle_t;
This is not a function pointer. This is a void pointer, which means it can point to basically any values. And this is a type, not a value, so app_driver_handle_t does not actually contain any pointers at all; it's merely a name that's synonymous with void*.
app_driver_handle_t = app_driver_button_init();
Given the typedef above, this syntax is never valid. You're setting a type equal to what is presumably a function call. You can't assign to types. Full stop.
What you can do is declare variables and assign them the result of function calls.
app_driver_handle_t my_variable;
my_variable = app_driver_button_init();
or you can do it in one line.
app_driver_handle_t my_variable = app_driver_button_init();
Finally, these last two lines.
app_driver_handle_t app_driver_light_init();
app_driver_handle_t app_driver_button_init();
These are also not function pointers. These are function prototypes. They're a promise to the compiler, saying, "I will eventually define two functions called app_driver_light_init and app_driver_button_init. These two functions will take no arguments and will return a void*". There's still no function pointer happening here. The functions, when they're eventually defined, will return a void*, which, again, is not a function pointer but a pointer to void.

This is effectively same as
void * app_driver_light_init();
void * app_driver_button_init();
These are not function pointers, they are functions that return void*.
A typedef'd fucntion pointer would look like this:
typedef void* (*app_driver_light_init)();

Related

Specific C++ notation for function arguments? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
This is a simple question, but I couldn't find the answer through searching online. I was trying to work through some leetcode problems to better my understanding of C++. I was wondering if someone could walk me through the meaning behind the creation of this function.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
}
};
I understand that public is used so that we can access ____ outside the Solution class, but I am not sure what exactly... it also looks like we are initializing a vector of integers named "twoSum" with the arguments of a vector of numbers and a target value... I was wondering what the meaning of the & is... etc. I guess a simple question would be can someone translate this block of code so that I can write my own versions for various problems (it seems like this is a constant block (or variation of a similar block) of code that is common throughout these leetcode problems).
The shown code snippet, defines a member function named twoSum that has the return type of vector<int> and has 2 parameters. The first parameter named nums is an lvalue reference to a non-const vector<int> while the second parameter named target is an int.
I was wondering what the meaning of the & is
The & in the first parameter nums of the member function means that nums is an lvalue reference to a non-const vector<int>. Meaning, the argument that will be passed to the nums parameter, will be passed by reference instead of passed by value. That is, inside the member function twoSums, the nums refer to the original vector<int> that is passed as an argument.
Also note that there should be a return statement inside the member function since the return type of the member function is non-void.

Return a functor based on command line input [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
From command line input I am receiving a single char of '=','<', or '>' followed by a value and my goal is to iterate through and modify my underlying data container using a custom functor (for example using remove_if). The simple but slow solution would be to have a single functor that is constructed using the input char and switching between the operators within it. However, this requires a check on the operator type every time the functor's operator is called. My first solution was using a switch statement on the char and creating a base functor class with 3 derived classes. However, I realized that while this was a completely viable and fast solution, I ended up having a large amount of code duplication of the switch statements. My attempt at a solution to this was using polymorphism and having a function that accepted the input char and returned a pointer of the base class which had a virtual () operator. However, when I passed the dereferenced base class pointer, it would not accept a pure virtual() operator and it was not overriden by the operators of the derived classes. In a sense, I want a function that returns a particular lambda or comparator assosciated with the value of an input char. What would be a good way of going about this?
Since lambdas have there own type i am not aware of a way to construct a function that returns different lambdas. You could store them in std:: function and pay for the overhead.
I think a combination of function ptr and map might be a good solution. Consider using a constexpr map (like in https://youtu.be/INn3xa4pMfg), create your functions and store the mapping in that map.
Note that you can also convert a non capturing lambda to a funtion ptr using ClosureType::operator ret(*)(params)() (See https://en.cppreference.com/w/cpp/language/lambda).

Which are the differences between generic pointer in C and generic pointer in C++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
For my exam I must be explain differences of the generic pointer (void *) in C and C++. They are two different things, but I can't find the differences between them.
In C, a void * pointer implicitly casts to any other pointer type. In C++, this cast must be made explicitly.
In C, malloc is used and we have Do I cast the result of malloc? (no); while in C++ malloc is frowned upon, the cast is required, but failing to include stdlib.h is a compile error. new returns the correct pointer type.
Other things went similar in C++; you shouldn't be downcasting void * much anymore. I only do it when interoping with C code or weird code optimization where template <class T> uses lots of T* and I can do most of the work in a non-generic base class (very rare).
However neither language quite has generic pointers. void * and void (*)() are not actually required to be the same size. void (*)() is used for the generic function pointer. In C, implicitly casting to/from it is a warning while in C++ this is an error. Most people cast explicitly in C because suppressing all "suspicious pointer conversion" warnings is a bad idea.

error: invalid use of void expression, C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am trying to implement a Menu system for a school project, where I have a STL Map containing function pointers in the form of
map<string, YMenu>
When I try to call a member function from within YMenu to add a new function pointer to a vector through the map, I get an error saying that it's an "invalid use of void expression." I have attached the relevant code below.
Vector holding arrays:
vector<void (*) () > nextAction;
Function to add function pointers:
void YMenu::addNextAction(int index, void (*Action)() )
{
nextAction[index] = Action;
}
Syntax used when calling member function which generated the Error:
Menus["0.0"].addNextAction(1, Menus["0.1"].show());
Any ideas for possible solutions? I have tried to find on google and searching here but can't seem to find an answer. :/
SOLVED: Thanks guys, apparently I made some stupid mistakes back there. I have finally managed to implement the code and get it to compile and run by using std::function and std::bind().
The type of Menues["0.1"].show() isn't a function pointer. It is the result of calling show() on a specific object. It seems, your show() function returns int. You won't have much fun trying to shove the function into a void(*)() in any shape or form!
What you are probably looking for is std::function<void()> which can be used to invoke a nullary function object, i.e., something which can be called without a parameter. The function you want to pass seems to be a member function and as such it actually has a parameter, the implicitly passed this pointer. You also want to ignore the return type which std::function<void()> will happily to do for you. That is, your nextAction vector would be declared as
std::vector<std::function<void()> nextAction;
However, to actually add the show function with the correct object, you need to also construct a suitbale std::function<void()> object: since your member function needs an object, you'll need to bind the object to the function, e.g.:
Menues["0.0"].addNextAction(1, std::bind(&YMenu::show, &Menus["0.1"]));
Also note that using nextAction[index] is only valid if index < nextAction.size() prior to this operation, i.e., std::vector<T> doesn't automatically resize to the proper size to accommodate a new index: that has to be explicitly for std::vector<T>.
With Menus["0.1"].show() you are calling the function.
You also can't store pointers to member functions like you try to do, unless you actually have the object instance when you finally call the member function pointer. I suggest you look into std::function and std::bind:
std::vector<std::function<void()> nextAction;
nextAction.push_back(std::bind(&YMenu::show, &Menus["0.1"]));
Instead of using C-style function pointers, use a combination of std::function and std::bind as follows:
std::vector<std::function<void()> > nextAction;
void YMenu::addNextAction(int index, std::function<void()> Action)
{
nextAction[index] = Action;
}
Menus["0.0"].addNextAction(1, std::bind(&YMenu::show, &Menus["0.1"]));

Why was the ampersand chosen as the symbol for references in C++? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Does anyone have an idea why the ampersand was chosen as the way to denote references in C++?
AFAIK (though I don't have the book near me), Stroustroup didn't explain that choice, which I find a little odd because the same symbol was already used for address-of in C.
In addition to Earwicker's response which I generally agree with. I would also speculate that since & is the "address-of" operator, it is somewhat fitting. Since a reference in many ways is like passing by address instead of by value.
In addition to that, taking the address of a variable is often referred to as "referencing"
(Yes I know that references don't have to be implemented using pointers under the hood, I am referring to the way they conceptually work).
This is just speculation though.
Stroustrup was always very reluctant to introduce a new reserved symbol or name, so he probably used it to avoid making the feature look weird to users of C.
Who knows why Stroustrup does anything, but my guess is that because the implementation of reference parameters involves passing the address of an lvalue, Stroustrup chose the C address-of operator because it would give C programmers the right idea about the cost model.
Here is my theory on that. I think it has much to do with what operators are valid (syntactically) for symbols. Consider
int a[1]; // a[1] is valid (syntactically)
int *a; // *a is valid
int a(char, bool); // a(<a char>, <a bool>) is valid (function call)
int C::*a; // <a C>.*a is valid
Conceptually, in those declarations what is named with a type (C, char, bool) is substituted with an expression of that type later on. Of course the intention is to reuse as much of the existing language as possible. So i think he used &:
int &a; // &a is valid
The important one is that & is only valid on the kind of expression a reference denotes: For lvalues. References are lvalues (named variables are too) and only for them & can be applied:
int &g(); // &g() is valid (taking the address of the referred to integer)
int g(); // &g() is *not* valid (can't apply to temporary int)
My thought was that there are 2 symbols used in pointers: * and &.
since int* means a pointer to an int, probably Stroustrup didn't want to introduce a whole new symbol. Since references are sort of like pointers, he stuck with &. Plus, the only previously valid use of & was to take the address of something, so it was OK to use in declarations.