A simple cout << endl fix a bug. What is happening?

Hi,
I’ve got a really strange behavior. My program works as expected with this code:

void Object::updateMatrix() const
	{
		mat = glm::translate( glm::mat4(), glm::vec3( x, y, 0.f ) ) ;
		mat = glm::rotate( mat, rotation, glm::vec3( 0.f, 0.f, 1.f ) ) ;
		mat = glm::scale( mat, glm::vec3( scaleX, scaleY, 1.f ) ) ;
		mat = glm::translate( mat, glm::vec3( -anchorX, -anchorY, 0.f ) ) ;
		cout << endl;
		imat = glm::inverse( mat ) ;
		needMatrixUpdate = false ;
	}

But when I remove the cout line, the program run like if the line marked with a [*] has no effect:

void Object::updateMatrix() const
	{
		mat = glm::translate( glm::mat4(), glm::vec3( x, y, 0.f ) ) ;
		mat = glm::rotate( mat, rotation, glm::vec3( 0.f, 0.f, 1.f ) ) ;
		mat = glm::scale( mat, glm::vec3( scaleX, scaleY, 1.f ) ) ;
		mat = glm::translate( mat, glm::vec3( -anchorX, -anchorY, 0.f ) ) ; // [*]
		imat = glm::inverse( mat ) ;
		needMatrixUpdate = false ;
	}

Another way to fix it is:

void Object::updateMatrix() const
	{
		mat = glm::translate( glm::mat4(), glm::vec3( x, y, 0.f ) ) ;
		mat = glm::rotate( mat, rotation, glm::vec3( 0.f, 0.f, 1.f ) ) ;
		auto mat2 = glm::scale( mat, glm::vec3( scaleX, scaleY, 1.f ) ) ;
		mat = glm::translate( mat2, glm::vec3( -anchorX, -anchorY, 0.f ) ) ;
		imat = glm::inverse( mat ) ;
		needMatrixUpdate = false ;
	}

I can’t figure what is happening here. Where is the bug ? in OF ? in gcc ? in glm ? between the keyboard and the chair ? (yeah, probably the last one)

I have tried to reproduce this bug in a minimal application, but it disappear when I try to isolate it. If you want to have a look, here’s the thing I’m currently coding, this is not so big, the problematic method is in c2d/Object.cpp, line 167
src.zip (8,6 Ko)

The right behavior is that an object must be selected on mouse click. If you delete the line 173 the bug appear.
I’m puzzled, so any thought is welcome :slight_smile:

I ran into similar problems with the previous lines too. Now I do:

	void Object::updateMatrix() const
	{
		auto mat1 = glm::translate( glm::mat4(), glm::vec3( x, y, 0.f ) ) ;
		auto mat2 = glm::rotate( mat1, rotation, glm::vec3( 0.f, 0.f, 1.f ) ) ;
		auto mat3 = glm::scale( mat2, glm::vec3( scaleX, scaleY, 1.f ) ) ;
		mat = glm::translate( mat3, glm::vec3( -anchorX, -anchorY, 0.f ) ) ;
		imat = glm::inverse( mat ) ;
		needMatrixUpdate = false ;
	}

which solve the problem but I still doesn’t understand what’s happening.

Random and unexplainable errors like these may be a sign of memory corruption, like some wild pointer changing data where it shouldn’t. Are you sure the object you are calling methods of is correctly constructed and valid?

Is there any difference if you build in Debug vs Release mode?

I’m not familiar with glm and didn’t look up that function but my first thought is…

Maybe a timing issue, where the work of those methods isn’t necessary complete when it returns - like it sends some work to a GPU and returns, but the GPU hasn’t necessarily really finished doing its thing, so when you re-use the same mat, the later function might actually get performed on it before the second one on the GPU, so the result of the later one gets stomped by an earlier one?

Thank you for the inputs !

I’m in the middle of something else, I will be back later to this topic :slight_smile:

it seems like your compiler “optimizes” that line away …but when you put the “cout” or a copy it doesn’t, you can see the assembly part to be sure…

what c++ dialect and what compiler are you using?
I really don’t like the way you combine templates, inheritance and overwrite

/*EDIT

The reason why I don’t think is a simple memory mismanagement issue but a dialect/design issue it’s because you seem to use shared pointers. (You don’t manually manage your memory with new and delete) and at the same time you use inheritance and templates in a weird manner. (that shouldn’t compile with c++98)

Just because you use shared ptr it doesn’t mean you still don’t have to manage your memory
(by making sure things are kept in scope)

I haven’t looked through your code but my first thought, when i see an app’s behavior change via a line of code or not is to check for memory errors, either in the form of uninitialized variables or in things like array access out of bounds, etc. Memory errors tend to produce “undefined” behavior which changes as the memory layout of your code changes, say by adding or removing a line of code.