Search code examples
c++sdl

C++/SDL "initial value of reference to a non-const must be an lvalue"


i have a player class in which i have a function to return a SDL_Rect for the dimensions and the position of my player object:

SDL_Rect Player::pos() 
{
    return SDL_Rect { mPosX, mPosY, PLAYER_WIDTH, PLAYER_HEIGHT };
}

When i use this in my main program to render the player with:

Renderer::Draw(img, player.pos(), NULL, angle);

i get the error: "initial value of reference to a non-const must be an lvalue" but when i instead write:

SDL_Rect pos = player.pos();
Renderer::Draw(img, pos, NULL, angle);

it works. Why cant i use player.pos() directly and have to use another SLD_Rect variable?


Solution

  • Renderer::Draw declares to modify its second argument (otherwise it would be const and you wouldnt get that error), if you pass a temporary then modifying the argument is pointless and it is most likely an error, thats why it is forbidden.

    Consider this example:

    int foo() { return 3; }
    void bar(int& x) { ++x; }
    void moo(const int& x) {}
    
    int main() {
        bar(foo()); // not allowed
        moo(foo()); // ok     
    
        int x = foo(); 
        bar(x);     // ok, modifies x
    }
    

    If bar(foo()) would be allowed, nothing super bad would happen. On the other hand there is no reason to allow it. bar explicitly declares that it wants to modify its argument so why allow to pass something when you have no way to observe that modification?

    PS: If you think this answer is too handwavy, may I refer you to the comment by @DanielLangr:

    Short answer: Because lvalue references cannot bind rvalues.