Handmade Hero » Forums » Code » Creating Local Copies of Struct Members
JohnBrexton
John Brexton
2 posts
#16097 Creating Local Copies of Struct Members
3 months, 2 weeks ago Edited by John Brexton on Aug. 26, 2018, 1:29 a.m.

Hey guys, I am a bit of a beginner (on episode 7 of HMH). I had a shower thought today, and just thought I might ask on here. I was just wondering in this simplified version of the XInput code that Casey wrote:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
for (DWORD ControllerIndex = 0;
     ControllerIndex < XUSER_MAX_COUNT;
     ++ControllerIndex)
{
    XINPUT_STATE ControllerState;
    if(XInputGetState(ControllerIndex, &ControllerState) == ERROR_SUCCESS)
    {
        XINPUT_GAMEPAD *Pad = &ControllerState.Gamepad;

        int16 StickX = Pad->sThumbLX;
        int16 StickY = Pad->sThumbLY;
    }
}


we created local variables StickX and StickY which simply store the values of the variables in the Pad Struct. my question is, will the compiler actually push space for StickX and StickY on the stack if all we ever do is read from them, or would MSVC be intelligent enough to know that StickX and StickY simply refer to Pad's members, in order to save space on the stack (this is assuming these ints aren't stored in registers for the entirety of the function and actually need to be loaded from memory at some point)?
mmozeiko
Mārtiņš Možeiko
1831 posts / 1 project
#16098 Creating Local Copies of Struct Members
3 months, 2 weeks ago Edited by Mārtiņš Možeiko on Aug. 26, 2018, 10:28 a.m.

It depends on code around it. But as you say, compiler may decide to not put values on stack, but directly read them from struct when you are using StickX/Y local variables. Compiler is allowed to do so. It could also decide to keep these values in register and not put on stack. Having local variable in C does not mean they *always* reserve space on stack. Values are put on stack only in case compiler runs out of registers when doing other calculations.

Here's an example: https://godbolt.org/z/2bkpvJ
As you can see in disassembly, the compiler directly uses values from memory in calculation - first one to initialize return value (sum, stored in eax register). And second one in += calculation.

Here's different example: https://godbolt.org/z/GM0Ib7
There compiler stored x and y values in registers (eax and edx)

Here's third example: https://godbolt.org/z/9hx4ob
Here compiler run out of registers, so it put x and y values on stack (x$1$[rsp] and y$1$[rsp] locations)
JohnBrexton
John Brexton
2 posts
#16100 Creating Local Copies of Struct Members
3 months, 2 weeks ago

awesome! such a useful website too. so much easier than creating a test VS project just to look at the disassembly.