Function returning function pointer from table as a parameter - c++

I have been reading for a while, but today I can't figure someting out and find a solution.
How to return a function pointer from a function table as parameter? All similair solutions don't work for this one and end up not compiling.
I have tried a lot of methods but the compiler always returns with errors like:
function returning function is not allowed solution (when using typedef void (*func)();)
As NO parameters have to be passed into the final routine it should be possible.
My simplified example:
void PrintOne(void) { printf("One")};
void PrintTwo(void) { printf("Two")};
struct ScanListStruct
{
int Value;
void (*Routine)(void);
}
const ScanListStruct DoList[] =
{
{1, PrintOne},
{2, PrintTwo}
}
bool GetRoutine(void *Ptr, int Nr)
{
for (int x =0; x<=1; x++)
{
if (DoList[x].Value = Nr)
{
Ptr = DoList[(x)].Routine;
//((*DoList[(x)].Routine)()); // Original Working and executing version!
return true;
}
}
return false;
}
void main(void)
{
int y = 1;
void (*RoutineInMain)(); // Define
if (GetRoutine( RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
}

There a few things wrong with the code;
Syntax errors (missing ; etc.)
main must return int
GetRoutine should accept the function pointer by reference, not just a void* pointer to anything
if condition should contain an equality test, not an assignment
As follows, works as expected;
void PrintOne(void) { printf("One"); };
void PrintTwo(void) { printf("Two"); };
struct ScanListStruct
{
int Value;
void (*Routine)(void);
};
const ScanListStruct DoList[] =
{
{1, &PrintOne},
{2, &PrintTwo}
};
bool GetRoutine(void (*&Ptr)(), int Nr)
{
for (int x =0; x<=1; x++)
{
if (DoList[x].Value == Nr)
{
Ptr = *DoList[(x)].Routine;
//((*DoList[(x)].Routine)()); // Original Working and executing version!
return true;
}
}
return false;
}
int main(void)
{
int y = 1;
void (*RoutineInMain)(); // Define
if (GetRoutine( RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
}
Prints One.

You have lots of errors in your code. Like here you put the comas at the wrong place:
void PrintOne(void) { printf("One")};
void PrintTwo(void) { printf("Two")};
It should be
void PrintOne(void) { printf("One");}
void PrintTwo(void) { printf("Two");}
And here you are using the wrong operator, = instead of ==.
if (DoList[x].Value = Nr)
When the argument Ptr is a pointer, and that is passed by value, so the value assigned in the function will not be available when the function returns.
This is how your code should be:
void PrintOne(void) { printf("One"); }
void PrintTwo(void) { printf("Two"); }
typedef void(*prototype)();
struct ScanListStruct
{
int Value;
prototype Routine;
};
const ScanListStruct DoList[] =
{
{ 1, PrintOne },
{ 2, PrintTwo }
};
bool GetRoutine(prototype &Ptr, int Nr)
{
for (int x = 0; x <= 1; x++)
{
if (DoList[x].Value == Nr)
{
Ptr = DoList[(x)].Routine;
return true;
}
}
return false;
}
int main()
{
int y = 1;
prototype RoutineInMain; // Define
if (GetRoutine(RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
return 0;
}

Related

How to insert statements at the beginning of a function block using Clang AST?

I am writing a source to source transformer using clang. I want to insert one flag variable for each parameter in a function. So if my original source is like below:
int f(int x, int y)
{
// do something ...
return 0;
}
I want to transform it to:
int f(int x, int y)
{
bool __flag_x = true;
bool __flag_y = true;
// do something ...
return 0
}
Instead I am getting:
int f(int x, int y)
bool __flag_x = true;
bool __flag_y = true;
{
// do something ...
return 0
}
The problem is, it is inserting the params before the left curly braces.
How do I insert it just after the brace?
Here is my AST matcher/rewriter:
bool VisitFunctionDecl(FunctionDecl *func) {
for (unsigned int i = 0; i < func->getNumParams(); i++) {
std::string varString = func->parameters()[i]->getQualifiedNameAsString();
TheRewriter.InsertText(func->getBody()->getBeginLoc(),
"bool __flag_" + varString + " = true;\n");
}
return true;
}

How to restructure this code without duplicating too much code?

class
{
public:
void func(const int val, const bool flag)
{
if(flag)
{
while(!lower.empty() && val <= lower.top())
{
// do a bunch of stuff with lower
}
}
else
{
while(!higher.empty() && val >= higher.top())
{
// do a bunch of stuff with higher, but it's the same stuff as would've done
// for lower
}
}
}
private:
std::stack<int> lower;
std::stack<int> higher;
}
I'm trying to figure out a better way to write the clauses because currently, I have a lot of duplicate code in both. The only difference is one clause operates on lower and the other on higher and the <= in the first clause is changed to >= higher in the second one.
I could wrap the clause in a helper function and call it in each clause (and pass in the lower and higher as an argument), e.g.,
class
{
public:
void func(const int val, const bool flag)
{
if(flag)
{
helper(lower, comparer);
}
else
{
helper(lower, comparer);
}
}
void helper(std::stack<int> &st)
{
// do a bunch of stuff with st
}
private:
std::stack<int> lower;
std::stack<int> higher;
}
I'm not sure if this is a good idea and if it is, I'm not sure how to get around the >= vs. <=. I'm hoping for suggestions on my design!
You can do something like the following:
class
{
public:
void func(const int val, const bool flag)
{
std::stack<int> *st;
bool (*compare)(int, int);
if (flag)
{
st = &lower;
compare = [](int a, int b){ return a <= b; };
}
else
{
st = &higher;
compare = [](int a, int b){ return a >= b; };
}
while (!st->empty() && compare(val, st->top()))
{
// do a bunch of stuff with *st
}
}
private:
std::stack<int> lower;
std::stack<int> higher;
}
Alternatively, using a helper would certainly work, too:
class
{
public:
void func(const int val, const bool flag)
{
if (flag)
func_helper(lower, val, std::less_equal{});
else
func_helper(higher, val, std::greater_equal{});
}
private:
std::stack<int> lower;
std::stack<int> higher;
template<typename Comparer>
void func_helper(stack<int> &st, const int val, Comparer compare)
{
while (!st.empty() && compare(val, st.top()))
{
// do a bunch of stuff with st
}
}
}
How about something like this
class
{
public:
void func(const int val, const bool flag)
{
int sign = 1;
std::stack<int>* higher_or_lower = &higher;
if(flag)
{
higher_or_lower = &lower;
sign = -1;
}
while(!higher_or_lower->empty() && sign*val >= sign*higher_or_lower->top())
{
// do a bunch of stuff with higher_or_lower
}
}
private:
std::stack<int> lower;
std::stack<int> higher;
}
The higher_or_lower covers both stacks and the sign takes care of less than vs. greater than.
Or a bit more compact:
class C
{
public:
void func(const int val, const bool flag)
{
const std::stack<int>* st[] = {&lower, &higher};
bool (*compare[])(int, int) = { [](int a, int b) { return a <= b; } , [](int a, int b) { return a >= b; } };
while (!st[flag]->empty() && compare[flag](val, st[flag]->top()))
{
// do a bunch of stuff with *st
}
}
private:
std::stack<int> lower;
std::stack<int> higher;
};

C++, "friend class" that's defined in the same header

I'm following this tutorial to create a simple iterator, although they are iterating primitive int, I'm iterating an object type SpamValue.
I have class called SpamValue and another called SpamValueStackIter and they are tightly coupled, because I didn't want to expose a lot of getters, so I made one class SpamValueStackIter a "friend class" in SpamValue header.
#ifndef SPAMSTACK_H
#define SPAMSTACK_H
#include <iostream>
#include "SpamValue.h"
using namespace std;
class SpamStack
{
public:
friend class SpamValueStackIter;
SpamStack(SpamValue** SpamValueItems, int size)
{
_position =-1;
_total_size = size;
_SpamValueItems = new SpamValue*[_total_size];
int i=0;
for (; i<_total_size; i++)
{
this->_SpamValueItems[i] = SpamValueItems[i];
}
}
~SpamStack()
{
if (NULL!=_SpamValueItems)
{
/*delete each*/
int i =0;
for (; i<_total_size; i++)
{
if (NULL!=_SpamValueItems[i])
{
delete _SpamValueItems[i];
}
}
/*delete the array*/
delete [] _SpamValueItems;
}
}
/*push*/
void push(SpamValue* SpamValue)
{
_SpamValueItems[++_position];
}
/*pop*/
SpamValue* pop()
{
return _SpamValueItems[_position--];
}
/*isEmpty*/
bool isEmpty()
{
return (_position == -1);
}
/*getters*/
SpamValue** getSpamValueItems()
{
return this->_SpamValueItems;
}
int getTotalSize()
{
return _total_size;
}
SpamValueStackIter* createIterator()const;
private:
SpamValue** _SpamValueItems;
int _total_size;
int _position;
};
class SpamValueStackIter
{
const SpamStack* _stack;
int _index;
public:
SpamValueStackIter(const SpamStack *s)
{
_stack = s;
}
/*set index position to first item*/
void first()
{
_index = 0;
}
/*set index position to the next item in the iterator*/
void next()
{
_index++;
}
/*is the iteration completed */
bool isDone()
{
return _index == _stack->_position + 1;
}
/* return the current item */
SpamValue* currentItem()
{
return _stack->_SpamValueItems[index];
}
/*create a new iterator*/
SpamValueStackIter* SpamStack::createIterator()const
{
return new SpamValueStackIter(this);
}
};
#endif /* SPAMSTACK_H*/
In the SpamStack.h:, Im getting this error:
SpamStack.h:77:6: error: ‘SpamValueStackIter’ does not name a type
SpamValueStackIter* createIterator()const;
And also:
SpamStack.h:121:52: error: cannot define member function ‘SpamStack::createIterator tor’ within ‘SpamValueStackIter’
SpamValueStackIter* SpamStack::createIterator()const
Why can't SpamStack resolve the "friend class" that's defined in the same header?
After forward declaration, as suggested by others:
#ifndef SPAMSTACK_H
#define SPAMSTACK_H
#include <iostream>
#include "SpamValue.h"
using namespace std;
/*forward declare*/
class SpamValueStackIter;
class SpamStack
{
public:
friend class SpamValueStackIter;
SpamStack(SpamValue** SpamValueItems, int size)
{
_position =-1;
_total_size = size;
_SpamValueItems = new SpamValue*[_total_size];
int i=0;
for (; i<_total_size; i++)
{
this->_SpamValueItems[i] = SpamValueItems[i];
}
}
~SpamStack()
{
if (NULL!=_SpamValueItems)
{
/*delete each*/
int i =0;
for (; i<_total_size; i++)
{
if (NULL!=_SpamValueItems[i])
{
delete _SpamValueItems[i];
}
}
/*delete the array*/
delete [] _SpamValueItems;
}
}
/*push*/
void push(SpamValue* SpamValue)
{
_SpamValueItems[++_position];
}
/*pop*/
SpamValue* pop()
{
return _SpamValueItems[_position--];
}
/*isEmpty*/
bool isEmpty()
{
return (_position == -1);
}
/*getters*/
SpamValue** getSpamValueItems()
{
return this->_SpamValueItems;
}
int getTotalSize()
{
return _total_size;
}
SpamValueStackIter* createIterator()const;
private:
SpamValue** _SpamValueItems;
int _total_size;
int _position;
};
class SpamValueStackIter
{
public:
SpamValueStackIter(const SpamStack *s)
{
_stack = s;
}
/*set index position to first item*/
void first()
{
_index = 0;
}
/*set index position to the next item in the iterator*/
void next()
{
_index++;
}
/*is the iteration completed */
bool isDone()
{
return _index == _stack->_position + 1;
}
/* return the current item */
SpamValue* currentItem()
{
return _stack->_SpamValueItems[index];
}
private:
const SpamStack* _stack;
int _index;
};
/create a new iterator/
SpamValueStackIter* SpamStack::createIterator()const
{
return new SpamValueStackIter(this);
}
#endif /* SPAMSTACK_H */
In getting this error now:
SpamStack.h:117:45: error: invalid types ‘SpamValue** const[<unresolved overloaded function type>]’ for array subscript
return _stack->_SpamValueItems[index];

2D Vectors Segmentation Fault:push_back

I am trying to solve a problem dealing with 2d vectors array.FunClass gets two parameters, number of sets and the lines per set.
The problem is whenever update_mytable function is being called a segmentation fault error pops up.During a quick search on stackoverflow I read that in most cases the issue for the seg-fault is because we are trying to access to a non-existed vector.But I don't think what I have the same issue here.
using std::vector;
typedef vector<mytable_entry>::iterator mytable_iter;
struct mytable_entry
{
int x_entry;
int y_entry;
};
mytable_entry new_mytable_entry(int new_ip, int new_target) {
mytable_entry new_entry;
new_entry.ip_entry = new_ip;
new_entry.target_entry = new_target;
return new_entry;
}
class FunClass : public BaseClass
{
public:
FunClass(unsigned mytable_sets, unsigned mytable_lines_per_set)
: table_sets(mytable_sets), table_assoc(mytable_lines_per_set)
{
mytable_table = vector< vector<mytable_entry> > (table_sets,vector< mytable_entry> (table_assoc));
}
~FunClass() {
/* Vectors will be decontructed automatially out of scope */
}
virtual bool predict(int x, int y) {
/* If mytable_entry exist return true, else false */
unsigned mytable_set_index = x % table_sets;
if (find_mytable_entry(mytable_table[mytable_set_index])) {
return true;
} else {
return false;
}
}
virtual void update(bool val1, bool val2, int x, int y) {
unsigned mytable_set_index = x % table_sets;
if (val1 == val2){
update_mytable_table(mytable_table[mytable_set_index],ip,target_entry,table_assoc);
}
void update_mytable(vector<mytable_entry> & mytable_set, int x, int y,unsigned table_assoc){
mytable_entry new_entry = new_mytable_entry(ip,target);
mytable_set.push_back(new_entry);
if (mytable_set.size() > table_assoc){
mytable_set.erase(mytable_set.begin());
}
}
bool find_mytable_entry(vector<mytable_entry> & mytable_set, int x) {
mytable_iter iter;
for (iter = mytable_set.begin(); iter != mytable_set.end(); iter++){
if ((*iter).ip_entry == ip) {
mytable_entry tmp_mytable_entry = (*iter);
mytable_set.erase(iter);
mytable_set.push_back(tmp_mytable_entry);
return true;
}
}
return false;
}
private:
vector< vector<mytable_entry> > mytable_table;
unsigned table_sets, table_assoc;
};
If I remove the mytable_set.push_back(new_entry); from update_mytable everything goes fine then.

function pointer for different functions with different data types or parameter

i have this code which uses a function pointer to point 3 functions sum, subtract, mul. it works well. but now the problem is that i have functions with different no.of parameters and different data types. how to implement this.
int add(int a, int b)
{
cout<<a+b;
}
int subtract(int a, int b)
{
cout<<a-b;
}
int mul(int a, int b)
{
cout<<a*b;
}
int main()
{
int (*fun_ptr_arr[])(int, int) = {add, subtract, mul};
unsigned int ch, a = 15, b = 10,c=9;
ch=2;
if (ch > 4) return 0;
(*fun_ptr_arr[ch])(a, b);
return 0;
}
The simple answer is that technically you can't do this. You could do some manipulations using an array as input for all these functions, but you will still have to know exactly what to pass to each function. From a software engineering perspective, you should not do this - I suggest you take a look at the nice answers here: C++ Function pointers with unknown number of arguments
A slightly different approach using objects to implement the required behavior. In order to have a truly generic kind of solution, we need to use Interfaces.
Dismantle the data and operation i.e keep them separately.
//Interface which describes any kind of data.
struct IData
{
virtual ~IData()
{
}
};
//Interface which desribes any kind of operation
struct IOperation
{
//actual operation which will be performed
virtual IData* Execute(IData *_pData) = 0;
virtual ~IOperation()
{
}
};
Now, every operation knows the kind of data it work on and will expect that kind of data only.
struct Operation_Add : public IOperation
{
//data for operation addition.
struct Data : public IData
{
int a;
int b;
int result;
};
IData* Execute(IData *_pData)
{
//expected data is "Operation_Add::Data_Add"
Operation_Add::Data *pData = dynamic_cast<Operation_Add::Data*>(_pData);
if(pData == NULL)
{
return NULL;
}
pData->result = pData->a + pData->b;
return pData;
}
};
struct Operation_Avg : public IOperation
{
//data for operation average of numbers.
struct Data : public IData
{
int a[5];
int total_numbers;
float result;
};
IData* Execute(IData *_pData)
{
//expected data is "Operation_Avg::Data_Avg"
Operation_Avg::Data *pData = dynamic_cast<Operation_Avg::Data*>(_pData);
if(pData == NULL)
{
return NULL;
}
pData->result = 0.0f;
for(int i = 0; i < pData->total_numbers; ++i)
{
pData->result += pData->a[i];
}
pData->result /= pData->total_numbers;
return pData;
}
};
Here, is the operation processor, the CPU.
struct CPU
{
enum OPERATION
{
ADDITION = 0,
AVERAGE
};
Operation_Add m_stAdditionOperation;
Operation_Avg m_stAverageOperation;
map<CPU::OPERATION, IOperation*> Operation;
CPU()
{
Operation[CPU::ADDITION] = &m_stAdditionOperation;
Operation[CPU::AVERAGE] = &m_stAverageOperation;
}
};
Sample:
CPU g_oCPU;
Operation_Add::Data stAdditionData;
stAdditionData.a = 10;
stAdditionData.b = 20;
Operation_Avg::Data stAverageData;
stAverageData.total_numbers = 5;
for(int i = 0; i < stAverageData.total_numbers; ++i)
{
stAverageData.a[i] = i*10;
}
Operation_Add::Data *pResultAdd = dynamic_cast<Operation_Add::Data*>(g_oCPU.Operation[CPU::ADDITION]->Execute(&stAdditionData));
if(pResultAdd != NULL)
{
printf("add = %d\n", pResultAdd->result);
}
Operation_Avg::Data *pResultAvg = dynamic_cast<Operation_Avg::Data*>(g_oCPU.Operation[CPU::AVERAGE]->Execute(&stAverageData));
if(pResultAvg != NULL)
{
printf("avg = %f\n", pResultAvg->result);
}
If you have the following functions
int f1(int i);
int f2(int i, int j);
You can define a generic function type like this
typedef int (*generic_fp)(void);
And then initialize your function array
generic_fp func_arr[2] = {
(generic_fp) f1,
(generic_fp) f2
};
But you will have to cast the functions back
int result_f1 = ((f1) func_arr[0]) (2);
int result_f2 = ((f2) func_arr[1]) (1, 2);
Obviously, it does not look like a good way to build a program
To make code look a little bit better you can define macros
#define F1(f, p1) ((f1)(f))(p1)
#define F2(f, p1, p2) ((f2)(f))(p1, p2)
int result_f1 = F1(func_arr[0], 2);
int result_f2 = F2(func_arr[1], 1, 2);
EDIT
Forgot to mention, you also have to define a type for every type of function
typedef int (*fi)(int); // type for function of one int param
typedef int (*fii)(int, int); // type for function of two int params
And to then cast stored pointers to those types
int result_f1 = ((fi) func_arr[0]) (2);
int result_f2 = ((fii) func_arr[1]) (1, 2);
Here is a complete example
#include <iostream>
typedef int (*generic_fp)(void);
typedef int (*fi)(int); // type for function of one int param
typedef int (*fii)(int, int); // type for function of two int params
#define F1(f, p1) ((fi)(f))(p1)
#define F2(f, p1, p2) ((fii)(f))(p1, p2)
int f1(int i);
int f2(int i, int j);
int main()
{
generic_fp func_arr[2] = {
(generic_fp) f1,
(generic_fp) f2
};
int result_f1_no_macro = ((fi) func_arr[0]) (2);
int result_f2_no_macro = ((fii) func_arr[1]) (1, 2);
int result_f1_macro = F1(func_arr[0], 2);
int result_f2_macro = F2(func_arr[1], 1, 2);
std::cout << result_f1_no_macro << ", " << result_f2_no_macro << std::endl;
std::cout << result_f1_macro << ", " << result_f2_macro << std::endl;
return 0;
}
int f1(int i)
{
return i * 2;
}
int f2(int i, int j)
{
return i + j;
}
The code above produces the following output
4, 3
4, 3