GetUserData == 0

edited June 2012 in Help request
Query.

In Debug mode, when using GetUserData while no userdata has been set, it will return 0.

In Release mode, it will return a random value.

Is it possible to always return 0 if there is no userdata to get?


EDIT: This may not be related to this; I seem to have more undefined problems in release, investigating.

EDIT/UPDATE: Hm, it seems to go wrong as soon as I put the Property 'Optimization' in Visual Studio (2008 express edition) to Maximize Speed (/O2) - putting that single value to Disabled and then it works fine.

The problematic bit is this:
		orxOBJECT* TempObject;
		for( // Grab the first object in our linked list, which is an orxOBJECT,
			TempObject = orxOBJECT( orxStructure_GetFirst( orxSTRUCTURE_ID_OBJECT ) );
			// Until we get one that's NULL,
			TempObject != orxNULL;
			// Continue onto the next object,
			TempObject = orxOBJECT( orxStructure_GetNext( TempObject ) ) )
		{
			GameObject* GObj = (GameObject*) orxObject_GetUserData(TempObject);
			if(GObj != orxNULL) GObj->Update(DT);
		}

Any ideas?

Comments

  • edited June 2012
    I'll double check tonight but everytime a structure is created we set all its content to zero, no matter the mode.
    If you could send me your project I could have a look locally. However i'm leaving tomorrow for 3 weeks so if I don't get it before tonight PDT, not sure when I'll be able to check. ;)
  • edited June 2012
    Yes, I had the same problem. You must set things to 0 if you intend for them to actually be zero. Upon instancing an item, it is usually filled with garbage (like in your release mode project). However, in debug mode, it is all instanced to 0/NULL/an equivalent.

    EDIT: I didn't see iarwain's post until just now; I was not talking about orx structures, just C/C++ variables. For optimization modes, it won't bother to set them to 0 (for speed's sake, I'm assuming).
  • edited June 2012
    Well, it was an orx structure, but i'll doublecheck if it works if i set the pointer to zero beforehand.

    I'll probably be too late dor that offer, iarwain, but i'll upload it for you when my computer is on and im out of bed.
  • edited June 2012
    http://www.gemblog.nl/B0UNCEORX.rar

    Make sure you change the dir to the SVN dir, I've tried explicitly changing the pointer to a null pointer but no such luck.

    As mentioned, Disable the optimization and it works fine, put it on the default Maximize Speed and it crashes.
  • edited June 2012
    I'm still up, I'm going to have a look right now. Thanks for the upload.
  • edited June 2012
    So I've just checked your code and the userdata looks correct to me, even with optimized code.

    With your current project, the first 2 objects of the list don't have a userdata but the third one has one (Player) and its value is correct.

    However we do crash after updating the player gameobject, I'm going to have a look at that right now. :)
  • edited June 2012
    Quick update:

    The stack pointer (ESP) doesn't get restored correctly at the end of your Player::Update() function and is 4 bytes off, which means exiting from this function sends us to an invalid position (if you trace in the asm window you'll see the call stack being correct till the ret 4 instruction is called and then all hell breaks loose).

    Now understanding why we get 4 bytes off when restoring the stack pointer is the next step. :)

    EDIT: Commenting out the call to GetMouseWorldPosition() and setting the vector to 0 will fix the ESP misbehavior and everything will run just fine.
    It probably comes from the function returning an orxVECTOR by copy and a probably SSE/alignment issue, going to look more into it, but a probably (untested) work around would be to change your function to GetMouseWorldPosition(orxVECTOR &_rvPos) instead.
  • edited June 2012
    Meh, my hypothesis was completely wrong, the optimized code of your project isn't using SSE at all, so no alignment issue.

    However it feels like it's a compiler optimization bug when trying to inline your GetMouseWorldPosition() helper function. The asm code results in an asymmetric number of stack push/pop, ending with the stacking pointer missing a pop (ie. 4 bytes).

    A super simple work around is to not use your helper function at all. :D
    This code works like a charm:
    orxBOOL Player::Update(float a_DT)
    {
      orxVECTOR mousepos;
      orxRender_GetWorldPosition(orxMouse_GetPosition(&mousepos), &mousepos);
    
      // ...
    }
    

    Otherwise, had a quick glance at your code, I have a couple of advices on how to use orx's features more efficiently if you're interested (like when creating Enemy and the current use of randoms, all this can be done completely in config). :)
  • edited June 2012
    Definitely a compiler optimization bug.

    One test you can do is change your GetMouseWorldPosition to take a orxS32 param (not a float as float are passed via the float stack to functions).

    Don't do anything with that orxS32 inside your function, don't even read it. And when calling it do mousepos = GetMouseWorldPosition(5461);

    Everything will work just fine, no extra pushes. -_-

    It's like with no parameters the compiler, after inlining, is trying to call the orx functions (orxMouse_GetPosition/orxRender_GetWorldPosition) with a stdcall calling convention instead of the fastcall one they're using. The info might get lost at some point but not when the wrapping function (yours) is taking parameters.

    Ah well, another microsoft oddity, I'll stop my investigation there. Have fun, 4AM here, time to get some rest! :)
  • edited June 2012
    Thank you, I'll have a poke at the mouse helper function (I had no clue this was any problem at all) - I had just copied it from i think Grey's example and was just using it like that :P

    Anyway, have a nice holiday or whatever you're going to do for 3 weeks, and see you after that ^_^

    EDIT: Also, mad respect for your assembler knowledge. I'm supposed to know some about it (so your ramblings make sense to me) but the depth you're going through it is commendable.

    EDIT2: Just thrown out the mousepos helper function, and now it works effortlessly. weird, but true.
  • edited June 2012
    Ahah, thank you!

    A long time ago asm was my first programming language, back when it was the demoscene that got me into coding. :) I don't have the skills of doing asm coding anymore but there's enough left to help for this kind of cases.

    As for Grey's version, I haven't tried it but it's possible that it might not be subject to the same optimization bug as his version is a method, albeit static, so the optimization path is C++ only whereas yours, being a plain function, could be a shared optim path with the C compiler. Worth a test, out of curiosity. :)
  • edited June 2012
    iarwain wrote:
    As for Grey's version, I haven't tried it but it's possible that it might not be subject to the same optimization bug as his version is a method, albeit static, so the optimization path is C++ only whereas yours, being a plain function, could be a shared optim path with the C compiler. Worth a test, out of curiosity. :)

    I'll have another stab at it, but i'm happy enough that it works now :P
Sign In or Register to comment.