在{}范围内声明变量时,它们是否仍会使用内存?

Kai*_*ije 8 c++ variables scope

在这个例子中,即使我永远不会使用变量WNDCLASSEX,x,y,cx,cy,当我在消息循环中时,它们仍将使用内存:

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpArgs, int iCmdShow)
    {
     WNDCLASSEX wc;
     ...
     RegisterClassEx(&wc);

     const int cx = 640;
     const int cy = 480; 
     // center of the screen
     int x = (GetSystemMetrics(SM_CXSCREEN) - cx) / 2;
     int y = (GetSystemMetrics(SM_CXSCREEN) - cy) / 2;

     CreateWindow(..., x, y, cx, cy, ...);

     MSG msg;

     while (GetMessage(&msg, NULL, 0, 0) > 0)
     {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
     }
     return 0;
    }
Run Code Online (Sandbox Code Playgroud)

但我想知道,如果我把它们放在一个范围内,它们仍会在消息循环中使用内存吗?例如

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpArgs, int iCmdShow)
{
 {
  WNDCLASSEX wc;
  ...
  RegisterClassEx(&wc);

  const int cx = 640;
  const int cy = 480; 
  // center of the screen
  int x = (GetSystemMetrics(SM_CXSCREEN) - cx) / 2;
  int y = (GetSystemMetrics(SM_CXSCREEN) - cy) / 2;

  CreateWindow(..., x, y, cx, cy, ...);
 }

 MSG msg;

 while (GetMessage(&msg, NULL, 0, 0) > 0)
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

或者如果我将它们分成两个函数并在winmain中调用它们,例如

wnd_register(hInst);
wnd_create(hInst);
Run Code Online (Sandbox Code Playgroud)

会阻止他们使用内存吗?

Mic*_*ael 6

编译器有很多余地来处理简单的本地,就像你在例子中一样.它们可能存在于堆栈中,它们可能仅作为机器代码中的直接值存在,或者它们可能只存在于寄存器中.堆栈空间通常在进入函数时分配.编译器将从堆栈指针中减去一些值,以便为所有本地生成空间.返回函数时,堆栈指针将恢复为原始值.这通常不会在退出不同范围块时完成.一旦不再使用变量,大多数编译器都会尝试积极地重用堆栈空间.在您的示例中,x和msg在堆栈上具有完全相同的地址是完全合法的,因为它们的使用是非重叠的.

我对这个问题的回答详细介绍了如何在堆栈上分配局部变量.

在您的示例中,常量cx和cy很可能在运行时没有内存支持它们,并且只是生成的代码中的立即值.x和y很可能会存在于寄存器中,直到需要将它们压入堆栈以调用CreateWindow.wc和msg几乎肯定会在堆栈中.

您不应该担心此级别的微优化 - 让编译器在其认为合适的情况下为局部变量分配空间.默认情况下,您有1 MB堆栈,这些变量消耗的数据量甚至不会记录为噪声.花时间担心更多有趣的问题.