静态在本地范围内

时间:2016-01-01 18:26:00

标签: c visual-c++ static

出于学习目的,我在回调函数中将变量声明为local_persist(静态)。如果我直接将变量声明为静态,则地址在每次调用时都会持续存在,并且我得到的正确行为是交替颜色。当我使用local_persist而不是static时会出现问题,然后在下次调用函数时它不会持久存在。使用VS2015 - MSVC:

#include <windows.h>

#define internal static;
#define global_variable static;
#define local_persist static;

INT m_ClientWidth = 1600;
INT m_ClientHeight = 900;
DWORD m_WndStyle = WS_OVERLAPPEDWINDOW;

HWND GetMainWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
void Update(float dt);
void Render(float dt);

LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }

        case WM_PAINT:
        {
            PAINTSTRUCT Paint;
            HDC DeviceContext = BeginPaint(hwnd, &Paint);
            int X = Paint.rcPaint.left;
            int Y = Paint.rcPaint.top;
            int Height = Paint.rcPaint.bottom - Paint.rcPaint.top;
            int Width =  Paint.rcPaint.right - Paint.rcPaint.left;
            local_persist DWORD Operation = WHITENESS;
            PatBlt(DeviceContext, X, Y, Width, Height, Operation);

            Operation = Operation == WHITENESS ? BLACKNESS : WHITENESS;
            EndPaint(hwnd, &Paint);
        }
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }   
}

int Run()
{
    MSG msg = { 0 };
    while (true)
    {
        if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);

            if(msg.message == WM_QUIT)
            {
                break;
            }
        }
        else
        {
            //Update
            Update(0.0f);
            //Render
            Render(0.0f);
        }
    }

    return static_cast<int>(msg.wParam);
}

void Update(float dt)
{

}

void Render(float dt)
{

}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND mainWindow = GetMainWindow(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

    if (mainWindow == NULL)
    {
        return 1;
    }

    ShowWindow(mainWindow, SW_SHOW);

    return Run();
}

HWND GetMainWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    //WNDCLASSEX
    WNDCLASSEX wcex;
    ZeroMemory(&wcex, sizeof(WNDCLASSEX));
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.hInstance = hInstance;
    wcex.lpfnWndProc = MsgProc;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = "MAINWINDCLASS";
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);


    if (!RegisterClassEx(&wcex))
    {
        OutputDebugString("\nFAILED TO REGISTER WINDOW CLASS\n");
        return NULL;
    }

    RECT r = { 0, 0, m_ClientWidth, m_ClientHeight };
    AdjustWindowRect(&r, m_WndStyle, FALSE);
    UINT width = r.right - r.left;
    UINT height = r.bottom - r.top;

    UINT x = GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2;
    UINT y = GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2;
    HWND m_hAppWnd = CreateWindow(wcex.lpszClassName, "Test Application", m_WndStyle, x, y, width, height, 0, 0, hInstance, 0);

    if (!m_hAppWnd)
    {
        OutputDebugString("\nFAILED TO CREATE WINDOW\n");
        return NULL;
    }

    return m_hAppWnd;
}

1 个答案:

答案 0 :(得分:1)

问题是您在宏定义的末尾有;

#define internal static;
#define global_variable static;
#define local_persist static;

所以当你写:

local_persist DWORD Operation = WHITENESS;

它扩展为:

static; DWORD Operation = WHITENESS;

分号结束陈述,因此它不属于Operation声明的一部分。

摆脱那些分号,它应该是:

#define internal static
#define global_variable static
#define local_persist static

然后local_persist的行为就像static