Necessity of declaration of function in c and cpp - aggregate-functions

From bruce eckel --" although u should always declare functions by including header file , functions declarations aren't' essential in c . Its possible in c but not cpp to call a function u havent declared. This is a dangerous practise because the c compiler may assume that a function that u call with an integer argument has an argument list containing integer even if it may actually contain float . This can produce bugs" my question is that even if a function is not declared , during its definition we have to mention the data type of arguments [ VOID FUNC( INT A)] , so how can a compiler assumes a float to be an integer??

The compiler makes assumption on supplied parameters if a function is not declared or defined prior to the point the assumption should be made. Try the following code and check the result (checked with gcc):
#include <stdio.h>
int main (int argc, char * argv[])
{
x(1);
x(1.);
x(1);
return 0;
}
void x(double y)
{
printf ("%f\n", y);
}

Related

Can argv** be returned as a function return value

In C we should return pointer variable if define as 1- static stack 2- Heap-allocated 3-const address.
The question is:
Can argv** variable in main function be returned as a function return value without undefined behaviour?
I can't imagine a situation which requires to return argv** from a function, but you get it from main (int argc, char* argv[]) so yes. You can pass it as a parameter to a function and return it to another function. They're like const for you.
You can't return pointer to the data allocated temporarily for the function's own needs. int* F{ int A; return &A; } will not work. But you can set int* A=(int*)malloc(sizeof(int)); and return A;: it'll be your tiny wrapper around the malloc function. You can even receive int* A as a parameter and return A+1; the rule you mentioned in the beginning actually means "there are some restrictions of allocation methods if you're planning to use the pointer after the function exits". You can break the rule without returning the value (for example, you can store the poiner in a global variable and it'll become invalid when the function exits, like void F{ int A; GlobPtr=&A; } which will cause the same problems).
But your function does not allocate argv, it's allocated before your code starts. So you can even shift it by one value as you extract parameters one-by-one, the returned pointer *nextargv[] will also point to valid memory area.

using `XPtr` to create pointer to a user defined function in Rcpp

--------- Adding a summary of the problem ---------------------------------
I want to create a externalpointer for a user defined function which can be passed to the another function. The user will provide function name as a string, my question is how can I convert that into a function pointer, after checking that the user provided string (say fstr) matches with the name of the function that was created by the user, i.e.
if (fstr == "<USER_DEFINED_FUNCTION_NAME>")
XPtr<funcPtr> fun(new funcPtr(&<USER_DEFINED_FUNCTION_NAME>), true);
else
Rcpp::Rcout << "Supply the correct function name" << std::endl;
since, I don't know the name of the function created by the user, essentially the problem is - how can I get the string stored in the variable fstr?
The full problem is described below. Of course, I could be thinking of this problem in a totally wrong way and there may be a better way to create a function pointer to a user defined function.
Thanks
I am writing a package which provides a wrapper around the cvode solver for solving ODEs from the SUNDIALS ODE solving C library. The C function which describes the right hand side of the ODEs must be have the signature
int <FUNCTION_NAME> (realtype t, N_Vector y, N_Vector ydot, void *user_data)
where realtype, N_Vector are datatypes defined in the library and t is time, y is the vector of states (dependent variables) and ydot is the rate of change of those variables w.r.t. time.
I have written a package which provides a wrapper around the cvode function in this library to solve ODEs expressed as above. The package source code can be found here. The cvode function can be used to solve the example in SUNDIALS provided as follows:
I create a test.cpp (pasted below) which describes the RHS of ODEs, it also has the exported function to create externalpointer for the function which gets exported to R. Note that NV_Ith_S is also defined by the library. Also, a good example about function pointers in Rcpp can be found here
First I run Rcpp::sourceCpp(test.cpp), then I run my_fun <- putFunPtrInXPtr() to create a external pointer my_fun to my test function in test.cpp. Finally, after loading the package, I run the command
time_t <- c(0.0, 0.4, seq(from = 10.4, len = 12, by = 10)) # time vector
cvode(time_t, c(1,0,0), my_fun, 1e-04, c(1e-08, 1e-08, 1e-08))
to get results on console successfully. Here the second argument is the initial conditions (IC), my_fun is the pointer to ODE function, third argument is relative tolerance and fourth argument is absolute tolerance. See details about cvode here.
My question is this - I want to change the cvode in my package so that it can take function name as a string, i.e. cvode(NumericVector time, NumericVector IC, std::string fstr, double reltol, NumericVector abstol), instead of cvode(NumericVector, NumericVector, SEXP, double, NumericVector) where the string (fstr) is the user given name which should be same as the same of the function defined in .cpp file (here test function in test.cpp).
I am thinking in my cvode function, I can write
if (fstr == "<USER_DEFINED_FUNCTION_NAME>")
XPtr<funcPtr> fun(new funcPtr(&<USER_DEFINED_FUNCTION_NAME>), true);
else
Rcpp::Rcout << "Supply the correct function name" << std::endl;
However, I cannot think of any way of getting information regarding the USER_DEFINED_FUNCTION_NAME. Essentially, I want fun to point to the USER_DEFINED_FUNCTION_NAME, but can't think of any way.
In the end, I actually want the RHS function defined in .cpp to have the signature int <FUNCTION_NAME>(double t, NumericVector y, NumericVector ydot, void *user_data), from which I create a function with the correct signature to be fed to cvode, but not sure how this is possible also.
I would be very thankful for any guidance. Thanks!
#include <Rcpp.h>
using namespace Rcpp;
#include <cvode/cvode.h> /* prototypes for CVODE fcts., consts. */
#include <nvector/nvector_serial.h> /* serial N_Vector types, fcts., macros */
#include <cvode/cvode_dense.h> /* prototype for CVDense */
#include <sundials/sundials_dense.h> /* definitions DlsMat DENSE_ELEM */
#include <sundials/sundials_types.h> /* definition of type realtype */
int test (realtype t, N_Vector y, N_Vector ydot, void *user_data){
// static keyword before int is not really required here
NV_Ith_S(ydot,0) = -0.04 * NV_Ith_S(y,0) + 1e04 * NV_Ith_S(y,1) * NV_Ith_S(y,2);
NV_Ith_S(ydot,2) = 3e07 * NV_Ith_S(y,1) * NV_Ith_S(y,1);
NV_Ith_S(ydot,1) = -NV_Ith_S(ydot,0) - NV_Ith_S(ydot,2);
return(0);
}
// declare funcPtr as a type for function pointer to a function with the
// signature same as function which describes the RHS for ODEs
// see reference here - http://gallery.rcpp.org/articles/passing-cpp-function-pointers/
typedef int (*funcPtr)(realtype t, N_Vector y, N_Vector ydot, void *user_data);
// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
// return(XPtr<funcPtr> (new funcPtr(&test)));
XPtr<funcPtr> testptr(new funcPtr(&test), true);
return testptr;
}

c - Array of pointer to functions, having different number of arguments

I am making a simple scheduler that executes functions contained in a FIFO queue.
Those functions have a same return type int, but have different number of int arguments.
I tried to implement it this way, but it does not seem to work. The compiler forbids conversion between int(*)() , int(*)(int), int(*)(int, int), or to any of those sort. (Arduino Sketch compiler)
Is there a way to solve this problem, or could you recommend a better way around? Thanks!
My code:
typedef int (*fnptr)(); // Tried this!
int foo(int var) {
return 0;
}
int main() {
fnptr fp = &foo; // error: invalid conversion from
// 'int (*)(int)' to 'int (*)()'
// [-fpermissive]
return 0;
}
You can cast:
fnptr fp = reinterpret_cast<fnptr>(foo);
The ()s are the "function call operator", adding them makes no sense at all in this situation, it changes the expression from "take the address of this function" to "take the address of this function's return value".
Note that aboev I don't even include the &, this is because the name of a function acts pretty much like a function pointer so it's already an address.

How can I store function pointer in vector?

like: vector<void *(*func)(void *)>...
You can declare a vector of pointers to functions taking a single void * argument and returning void * like this:
#include <vector>
std::vector<void *(*)(void *)> v;
If you want to store pointers to functions with varying prototypes, it becomes more difficult/dangerous. Then you must cast the functions to the right type when adding them to the vector and cast them back to the original prototype when calling. Just an example how ugly this gets:
#include <vector>
int mult(int a) { return 2*a; }
int main()
{
int b;
std::vector<void *(*)(void *)> v;
v.push_back((void *(*)(void *))mult);
b = ((int (*)(int)) v[0])(2); // The value of b is 4.
return 0;
}
You can use typedef's to partially hide the function casting syntax, but there is still the danger of calling a function as the wrong type, leading to crashes or other undefined behaviour. So don't do this.
// shorter
std::vector<int (*)(int)> v;
v.push_back(mult);
b = v[0](2); // The value of b is 4.
Storing a function in vector might be a difficult task as illustrated above. In that case if u want to dynamically use a function u can also store a function in pointer which is much easier. Main advantage of this is u can store any type of function either it is a normal function or a paramatrized one(having some input as parametrs). Complete process is described in the link given below with examples...just have a look...!!!
how can we store Function in pointer

Pointer won't return with assigned address

I'm using Qt Creator 4.5 with GCC 4.3 and I'm having the following problem that I am not sure is Qt or C++ related: I call a function with a char * as an input parameter. Inside that function I make a dynamic allocation and I assign the address to the char *. The problem is when the function returns it does not point to this address anymore.
bool FPSengine::putData (char CommandByte , int Index)
{
char *msgByte;
structSize=putDatagrams(CommandByte, Index, msgByte);
}
int FPSengine::putDatagrams (char CommandByte, int Index, char *msgByte)
{
int theSize;
switch ( CommandByte ) {
case (CHANGE_CONFIGURATION): {
theSize=sizeof(MsnConfigType);
msgByte=new char[theSize];
union MConfigUnion {
char cByte[sizeof(MsnConfigType)];
MsnConfigType m;
};
MConfigUnion * msnConfig=(MConfigUnion*)msgByte;
...Do some assignments. I verify and everything is OK.
}
}
return theSize;
}
When I return the pointer it contains a completely different address than the one assigned in putDatagrams(). Why?
...
Ok thx I understand my mistake(rookie mistake :( ). When sending a pointer as an input parameter to the function you send the address of your data but not the address of your pointer so you cant make the pointer point somewhere else...it is actually a local copy like Index. The only case the data would of been returned succesfully with the use of a char * is by allocating the memory before the function call:
bool FPSengine::putData (char CommandByte , int Index)
{
char *msgByte;
msgByte=new char[sizeof(MsnConfigType)];
structSize=putDatagrams(CommandByte, Index, msgByte);
}
int FPSengine::putDatagrams (char CommandByte, int Index, char *msgByte)
{
int theSize;
switch ( CommandByte ) {
case (CHANGE_CONFIGURATION): {
theSize=sizeof(MsnConfigType);
union MConfigUnion {
char cByte[sizeof(MsnConfigType)];
MsnConfigType m;
};
MConfigUnion * msnConfig=(MConfigUnion*)msgByte;
...Do some assignments. I verify and everything is OK.
}
}
return theSize;
}
There are two ways. The pass-by-value way (C style):
int FPSengine::putDatagrams (char CommandByte, int Index, char **msgByte)
Note the second * for msgByte. Then inside of putDatagrams(), do:
*msgByte = new char[theSize];
In fact, anywhere in that function where you currently have msgByte, use *msgByte. When calling putDatagrams(), do:
structSize=putDatagrams(CommandByte, Index, &msgByte);
And the second way, since you're in C++, you could use pass-by-reference. Just change the signature of putDatagrams() to:
int FPSengine::putDatagrams (char CommandByte, int Index, char * &msgByte)
And you should be good. In this case, you shouldn't need to modify the caller or anything inside of your putDatagrams() routine.
Well, yes. Everything in C++ is, by default, passed by value. Parameters in the call putDatagrams(a, b, c) are sent by value - you wouldn't expect assigning to index in the code to change the value of b at the call site. Your msgByte=new char[theSize]; is just assigning to the local variable msgByte, overwriting the value passed in.
If you want to change a passed parameter such that the call site variable changes, you'll need to either pass by reference, or (in this case) pass a "pointer to a pointer` (and deference away the first pointer, assigning to the actual pointer).

Resources