Error: taking address of temporary [-fpermissive]

I've been looking into this for a few hours, to no avail. Basically I have

struct rectangle { int x, y, w, h; }; rectangle player::RegionCoordinates() // Region Coord { rectangle temp; temp.x = colRegion.x + coordinates.x; temp.w = colRegion.w; temp.y = colRegion.y + coordinates.y; temp.h = colRegion.h; return temp; } // Collision detect function bool IsCollision (rectangle * r1, rectangle * r2) { if (r1->x < r2->x + r2->w && r1->x + r1->w > r2->x && r1->y < r2->y + r2->h && r1->y + r1->h > r2->y) { return true; } return false; } //blah blah main while loop if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates())) //ERROR { player1.score+=10; stick1.x = rand() % 600+1; stick1.y = rand() % 400+1; play_sample(pickup,128,128,1000,false); } 

Any ideas? I'm sure it's something really obvious but for the life of me I can't figure it out.

0

3 Answers

RegionCoordinates() returns an object by value. This means a call to RegionCoordinates() returns a temporary instance of rectangle. As the error says, you're trying to take the address of this temporary object, which is not legal in C++.

Why does IsCollision() take pointers anyway? It would be more natural to take its parameters by const reference:

bool IsCollision (const rectangle &r1, const rectangle &r2) { if (r1.x < r2.x + r2.w && r1.x + r1.w > r2.x && r1.y < r2.y + r2.h && r1.y + r1.h > r2.y) { return true; } return false; } //blah blah main while loop if (IsCollision(player1.RegionCoordinates(), stick1.RegionCoordinates())) //no error any more { player1.score+=10; stick1.x = rand() % 600+1; stick1.y = rand() % 400+1; play_sample(pickup,128,128,1000,false); } 

Since IsCollision takes a rectangle * and you are taking the address of the result here:

if (IsCollision(&player1.RegionCoordinates(), &stick1.RegionCoordinates())) 

You most likely are returning a rectangle back from RegionCoordinates() which is a temporary variable since it will disappear after the if statement is done. If you assign the result of RegionCoordinates() to a variable then it will no longer be a temporary and you can then take the address of it:

rectangle r1 = player1.RegionCoordinates() ; rectangle r2 = stick1.RegionCoordinates() ; if (IsCollision(&r1, &r2)) 

Alternatively you could take the parameters as const references which would be the more C++ way of doing it:

bool IsCollision (const rectangle &r1, const rectangle &r2) 
1

Given the kind of error you are getting, I must assume RegionCoordinates() is returning an object by value, thus causing the creation of a temporary, and you are taking the address of that temporary.

The address-of operator requires an lvalue as its operand, but you are applying it to an rvalue (temporaries are rvalues).

You could do this (if you are not using C++11, replace auto with the type returned by RegionCoordinates):

auto rcPlayer1 = player1.RegionCoordinates(); auto rcStick1 = player1.RegionCoordinates(); if (IsCollision(&rcPlayer1, &rcStick1)) //ERROR { player1.score+=10; stick1.x = rand() % 600+1; stick1.y = rand() % 400+1; play_sample(pickup,128,128,1000,false); } 

Alternatively, you can change IsCollision so that it accepts references rather than pointers, as suggested by Angew in his answer.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like