Possible casting issue in declaration of function in header file

In summary, the person is having trouble compiling a code which declares a function in the header file and its corresponding definition in the source code file. When they compile, they get an error that the function cannot be initialized because it is being used with an rvalue which is not a pointer to a function. They think the problem is related to how they declare the function in the header file, but they are not sure. They suggest using functors instead of function pointers.
  • #1
CAF123
Gold Member
2,948
88
Hello all, see below for a snippet of a header file, class1.h, and source code file, class1.cpp, adjusted to reproduce the issue I am having. I have declared a series of functions in the .h file and their corresponding definitions in the .cpp file but when I compile I get the error:

class1.cpp:48:57: error: cannot initialize a parameter of type 'double (*)(double, void *)'
with an rvalue of type 'double (class1::*)(double, void *)'
convolute1(lowerBound,split,epsabs,epsrel,toystruct1,&class1::func1);

I think it is to do with how I declare the function convolute1 in the .h file involving the pointer and maybe there is some casting issue. I have tried a few things including making the func1 static but this gives me problems elsewhere in the code (not reproduced in the toy files below) so I was wondering if anyone could see an issue immediately? Thanks!

Header file, class1.h:
C++:
class class1 {
 
  struct toystruct_t {
    double a,b,c;
    };

  double func1(double z, void *p);
  double func2(toystruct_t toystruct);
 
  double convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *));
    
};

Source code file, class1.cpp:
C++:
#include <iostream>
#include <gsl/gsl_integration.h>
#include <math.h>
#include <complex>
#include "class1.h"

 struct toystruct_t
      {
        double a,b,c;
      };double class1::func1(double z, void *p)
{
   
    return 2.0;   //function here made trival as reproduces error I wish to discuss without adding further complication
}
              
double class1::convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *))
{
    double result;
    double err;
    double res;
   
    gsl_integration_workspace * coeffIntegralWorkspace = gsl_integration_workspace_alloc (1e8);
    gsl_function F;
    F.params = (void*)(&toystruct);
    F.function = func;
    gsl_integration_qags(&F, lowerBoundary, upperBoundary,
                         epsabs, epsrel, 1e8,
                         coeffIntegralWorkspace, &result, &err);
   
    gsl_integration_workspace_free(coeffIntegralWorkspace);
   
    res = result;
   
    return res;
}

double class1::func2(toystruct_t toystruct1)
{
  double lowerBound = -10.0;
  double upperBound = -4.0;
  double epsabs=1e-3;
  double epsrel=1e-3;

  double res  =
   convolute1(lowerBound,upperBound,epsabs,epsrel,toystruct1,&class1::func1);

  return res;
}

int main(int argc, const char * argv[]) {
    
     std::cout << "Hello World"  << std::endl;
  
 }
 
Last edited by a moderator:
Technology news on Phys.org
  • #2
I might be wrong, but I think the problem comes where you call convolute1() in class1.cpp.
Change the last parameter in this call to get rid of &

C:
double res  =
   convolute1(lowerBound,upperBound,epsabs,epsrel,toystruct1,class1::func1);

The name of a function is an address -- the address of the entry point in the code for that function.
 
  • Like
Likes CAF123
  • #3
You shouldn't pass a non-static class member function as a parameter, and there is no need to: code inside class1::convolute1() can access the current instance's func1() member as this->func1().

Mark44 said:
The name of a function is an address -- the address of the entry point in the code for that function.
But that address is not what you want for a non-static member function as the code there is not bound to an instance. Non-static member functions should (can?) only be accessed via the object to which they are bound.
 
  • Like
Likes CAF123
  • #4
I took another look. You can't do this:
CAF123 said:
C++:
    F.params = (void*)(&toystruct);
    // func must be a pointer to an ordinary function, not a (non-static) class member function.
    F.function = func;
    gsl_integration_qags(&F, lowerBoundary, upperBoundary,
                         epsabs, epsrel, 1e8,
                         coeffIntegralWorkspace, &result, &err);

If you want a function that works with an instance of class1 (let's call it class1_obj although that's a terrible name) then you need to pass class1_obj as (part of) F.params which will be passed to your F.function as the params argument. F.function can then do params.class1_obj.func1().
 
  • Like
Likes CAF123
  • #5
CAF123 said:
class1.cpp:48:57: error: cannot initialize a parameter of type 'double (*)(double, void *)'
with an rvalue of type 'double (class1::*)(double, void *)'
convolute1(lowerBound,split,epsabs,epsrel,toystruct1,&class1::func1);

Have you considered using functors, instead function pointers?
https://stackoverflow.com/a/6451911
 
  • Like
Likes CAF123
  • #6
  • Like
Likes CAF123
  • #7
CAF123 said:
Hello all, see below for a snippet of a header file, class1.h, and source code file, class1.cpp, adjusted to reproduce the issue I am having. I have declared a series of functions in the .h file and their corresponding definitions in the .cpp file but when I compile I get the error:

class1.cpp:48:57: error: cannot initialize a parameter of type 'double (*)(double, void *)'
with an rvalue of type 'double (class1::*)(double, void *)'
convolute1(lowerBound,split,epsabs,epsrel,toystruct1,&class1::func1);

I think it is to do with how I declare the function convolute1 in the .h file involving the pointer and maybe there is some casting issue. I have tried a few things including making the func1 static but this gives me problems elsewhere in the code (not reproduced in the toy files below) so I was wondering if anyone could see an issue immediately? Thanks!

Header file, class1.h:
C++:
class class1 {
 
  struct toystruct_t {
    double a,b,c;
    };

  double func1(double z, void *p);
  double func2(toystruct_t toystruct);
 
  double convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *));
 
};

Source code file, class1.cpp:
C++:
#include <iostream>
#include <gsl/gsl_integration.h>
#include <math.h>
#include <complex>
#include "class1.h"

 struct toystruct_t
      {
        double a,b,c;
      };double class1::func1(double z, void *p)
{
 
    return 2.0;   //function here made trival as reproduces error I wish to discuss without adding further complication
}
           
double class1::convolute1(double lowerBoundary, double upperBoundary, double epsabs, double epsrel, toystruct_t toystruct, double func(double, void *))
{
    double result;
    double err;
    double res;
 
    gsl_integration_workspace * coeffIntegralWorkspace = gsl_integration_workspace_alloc (1e8);
    gsl_function F;
    F.params = (void*)(&toystruct);
    F.function = func;
    gsl_integration_qags(&F, lowerBoundary, upperBoundary,
                         epsabs, epsrel, 1e8,
                         coeffIntegralWorkspace, &result, &err);
 
    gsl_integration_workspace_free(coeffIntegralWorkspace);
 
    res = result;
 
    return res;
}

double class1::func2(toystruct_t toystruct1)
{
  double lowerBound = -10.0;
  double upperBound = -4.0;
  double epsabs=1e-3;
  double epsrel=1e-3;

  double res  =
   convolute1(lowerBound,upperBound,epsabs,epsrel,toystruct1,&class1::func1);

  return res;
}

int main(int argc, const char * argv[]) {
 
     std::cout << "Hello World"  << std::endl;
 
 }
I *think* (standards have changed rapidly), your last parameter should be declared as ``double (*func) (<etc>)``

Edit: it appears you are also trying to pass a member function as the last parameter. So the prototype is expecting something like a nonmember function, but in the implementation is an actual member function. I think that explains the error message.
 
Last edited:
  • Like
Likes CAF123

FAQ: Possible casting issue in declaration of function in header file

What is a possible casting issue in declaration of function in header file?

A casting issue in declaration of function in header file refers to a situation where the data type of a function's parameters in the header file does not match the data type of the same parameters in the function's definition. This can lead to errors or unexpected behavior when the function is called.

How does a casting issue in declaration of function in header file occur?

A casting issue in declaration of function in header file can occur when there is a mismatch in the data types used for the function's parameters between the header file and the function's definition. This can be caused by a mistake in the code or when different data types are used in different parts of the program.

What are the consequences of a casting issue in declaration of function in header file?

The consequences of a casting issue in declaration of function in header file can vary, but they often result in compilation errors or runtime errors when the function is called. This can lead to unexpected behavior or the program crashing.

How can a casting issue in declaration of function in header file be resolved?

To resolve a casting issue in declaration of function in header file, the data types used for the function's parameters in the header file and the function's definition must be consistent. This can be achieved by carefully checking the code and ensuring that the correct data types are used in both places.

Are there any best practices to prevent a casting issue in declaration of function in header file?

Yes, there are some best practices that can help prevent a casting issue in declaration of function in header file. These include using consistent data types throughout the code, avoiding unnecessary casting, and using explicit data type declarations for parameters in the function's definition.

Similar threads

Replies
2
Views
2K
Replies
2
Views
540
Back
Top