0

I have the following struct meant to store rgb values. I overloaded the common operators +, -, * for rgb and scalar operations.

struct rgb {
    float r;
    float g;
    float b;

    rgb() : r(0.f), g(0.f), b(0.f) {}
    rgb( const float& rr, const float& gg, const float& bb ): r(rr), g(gg), b(bb) {}
    rgb( const float& f ): r(f), g(f), b(f) {}

    rgb& operator +(const rgb& a) {
        rgb t;
        t.r = this->r + a.r;
        t.g = this->g + a.g;
        t.b = this->b + a.b;
        return t;
    }
    rgb& operator +(const float& a) {
        rgb t;
        t.r = this->r + a;
        t.g = this->g + a;
        t.b = this->b + a;
        return t;
    }
    rgb& operator -(const rgb& a) {
        rgb t;
        t.r = this->r - a.r;
        t.g = this->g - a.g;
        t.b = this->b - a.b;
        return t;
    }
    rgb& operator -(const float& a) {
        rgb t;
        t.r = this->r - a;
        t.g = this->g - a;
        t.b = this->b - a;
        return t;
    }
    rgb& operator *(const rgb& a) {
        rgb t;
        t.r = this->r * a.r;
        t.g = this->g * a.g;
        t.b = this->b * a.b;
        return t;
    }
    rgb& operator *(const float& a) {
        rgb t;
        t.r = this->r * a;
        t.g = this->g * a;
        t.b = this->b * a;
        return t;
    }
    float sum() {
        return r + g + b;
    }
};

When I use this struct in the following function, I get an unexpected output:

inline void foo(rgb &N,
                rgb &X,
                rgb &P,
                rgb &R) {
    float d = 0.0;
    rgb d_v;
    //find the dot product between N and (P-X)
    d_v = N * (P - X);  //this is always 0, 0, 0
    d = d_v.sum();
    R = P - N * d;
}

But if I use intermediary rgb's to store intermediate operations, it works fine:

inline void subspaceProjectCPU(rgb &N,
                           rgb &X,
                           rgb &P,
                           rgb &R) {
    float d = 0.0;
    rgb d_v;
    rgb PX = P - X;
    //find the dot product between N and (P-X)
    d_v = PX * N;
    d = d_v.sum();
    rgb Nd = N*d;
    R = P - Nd;
}

Can someone shed some lights on this? (I'm aware I didn't handle scalar operations on both sides, so N * d is defined but not d * N, where N is rgb and d is float).

p.i.g.
  • 2,815
  • 2
  • 24
  • 41
user2121792
  • 221
  • 1
  • 5
  • 12
  • 4
    opertors `+`, `-`, `*`, `/` etc. should not return a reference. What would that reference refer to anyway? Return by value instead. And look at http://stackoverflow.com/questions/4421706/operator-overloading – juanchopanza Jul 10 '15 at 16:12
  • If you overload an operator `@`, you should also overload `@=`. – celticminstrel Jul 10 '15 at 16:30

1 Answers1

2

Your operator functions return a reference to a local variable, which will cease to exist once the operator function returns. Don't do that; it's undefined behaviour. Just return an rgb value.

rici
  • 234,347
  • 28
  • 237
  • 341