Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an instance of object as function argument -- Does this code invoke undefined behavior?

This is a miniature version of a code I'm running in production. I have found that, my real code, behaves differently under gcc and Intel compilers and my best guess is an undefined behavior. Please consider the following sample code:

#include <iostream>

struct baseFunctor{
    virtual double operator()(double x) const = 0;
};

class mathObj{
    const baseFunctor *tmp1, *tmp2;
public:
    void set(const baseFunctor& b1, const baseFunctor& b2){
        tmp1 = &b1;
        tmp2 = &b2;
    }
    double getValue(double x){
        return (tmp1->operator()(x) + tmp2->operator()(x));
    }
};

int main () {
    mathObj obj;

    struct squareFunctor: public baseFunctor {
        double operator()(double x) const { return x*x; }
    };
    struct cubeFunctor: public baseFunctor {
        double operator()(double x) const { return x*x*x; }
    };

    obj.set(squareFunctor(), cubeFunctor());
    std::cout << obj.getValue(10) << std::endl; 
    return 0;
}

Could obj.set(squareFunctor(), cubeFunctor()); invoke undefined behavior?

like image 740
mmirzadeh Avatar asked Mar 07 '26 11:03

mmirzadeh


1 Answers

Yes it most definitely does, because you are storing pointers to temporary values that are destroyed at the end of the statement, and then using them. Using a destructed object is undefined behaviour.

You need to create the values separately, and then call set with them:

cubeFunctor cf;
squareFunctor sf;

obj.set(sf, cf);

Note that you cannot solve this problem by storing the functors by value (unless you use templates), because that would cause slicing.

Also as a side note, you can change getValue to do

return (*tmp1)(x) + (*tmp2)(x);

To make it look a little prettier (and you still get dynamic dispatch).

like image 83
Seth Carnegie Avatar answered Mar 10 '26 03:03

Seth Carnegie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!