Problem with functor and error handling

Feb 11, 2013 at 3:29pm
Hi, I need to evaluate mathematical functions. These functions might have singularities. So I need to check that evaluated value is valid. I can check
very easily that the value is (not) valid, but I don't know how can I transfer this validity information.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <cmath>

template<typename T>
class FunctionBase {         // Base class. Here I define a simple interface
public:                      // which evaluates the value of a function
	virtual T operator() (T x) = 0; 
 	virtual ~FunctionBase(){ }     // Virtual destructor
	virtual int getError() = 0;    // This should return error flag.
};

template<typename T, class parameters, typename S>
class Function : public FunctionBase<T> {  // Here I define derived class
public:
	typedef T definition( T, parameters&, S& );
        definition& function; // math functions are evaluated at point T x
	parameters& params;   // with parameters.
	S& error_flag;        // If value of the math function is not valid
        // then this value should change. But unfortunately it
        // doesn't. Overload () operator in function evaluations.
        virtual T operator() (T x){   
		return function( x, params, error_flag );
	}
	virtual ~Function(){ }
	int getError(){
		return error_flag;
	}
        // Constructors
	Function( definition& function_ ) : function( function_ ), params( 0 ), 
                    error_flag( 0 ) { }
	Function( definition& function_, parameters& params_, S error_flag_ )
		: function( function_ ), params( params_ ), 
                  error_flag( error_flag_ ) { }
};
// Example function
double fun( double x, double& alpha, int& error ){
	double result = alpha*x;
	if ( !isinf( result ) ){
		error = 0;
		return result;
	} else {
		error = 1;
		return 0.0;
	}
}

int main(){
	int status = 1;
	double x = 2.0;
	double a = 1;
	Function<double, double, int> F(fun, a, status);
	std::cout <<"val:" << F(x) << " status: " << F.getError() << std::endl;
	return 0;
}


In this case I want that F.getError() should return 0. But it returns value of
the variable "int status".
Feb 11, 2013 at 4:08pm
You are observing undefined behaviour.
The order of evaluation is not defined, so your compiler choose to execute `F.getError()' before `F(x)'
1
2
3
std::cout <<"val:" << F(x);
std::cout << " getError: " << F.getError();
std::cout << " status: " << status << std::endl;



If you do want to modify `status' you need to pass it by reference to the constructor
Function( definition& function_, parameters& params_, S& error_flag_ )
(I'm not sure how that could compile before, the other constructor does get labeled as illegal)
Feb 11, 2013 at 4:26pm
Ok. The first one helped. But I don't understand why I get this undefined behaviour. What should I do to get rid of this? Thank you very much.
Feb 11, 2013 at 4:36pm
The order of operations is defined - the stuff prints out left to right - but the order of evaluation, that is, when the compiler evaluates each expression, is not defined - the function calls on line 52 can happen in any order.
Feb 11, 2013 at 4:37pm
http://en.cppreference.com/w/cpp/language/eval_order
> What should I do to get rid of this?
Use another statement.
1
2
3
4
5
6
std::cout <<"val:" << F(x);
std::cout << " getError: " << F.getError();
//...
double value = F(x);
int error = F.getError();
std::cout << "val: " << value << " getError: " << error;
Feb 11, 2013 at 4:38pm
Ok. Thanks. Now I understand.
Topic archived. No new replies allowed.