c++ - C4533 警告 : why does goto skip variable initialization?

标签 c++

我得到:

warning C4533: initialization of 'b' is skipped by goto FreeDC.

但是如果代码到达WM_CREATE中的标签FreeDC,'b'不会被初始化。如果在那种情况下没有初始化,如何跳过它的初始化。我只是不明白这个警告。

#include <windows.h>

class A
{
    int i;

    public:
    A() {};
    A(int i) : i(i) {}
};

LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);

HINSTANCE ghInstance;

/************************************************************************************************************************

    WinMain(hInstance, hPrevInstance, pszCmdLine, nCmdShow)

************************************************************************************************************************/

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
    ghInstance = hInstance;

    WNDCLASSEX  wndclassx;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = CS_HREDRAW | CS_VREDRAW;
    wndclassx.lpfnWndProc   = WndProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = NULL;
    wndclassx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndclassx.lpszMenuName  = NULL;
    wndclassx.lpszClassName = L"WndProc";
    wndclassx.hIconSm       = NULL;

    if( !RegisterClassEx(&wndclassx) ) return 0;

    HWND hWnd = CreateWindow(L"WndProc", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                             CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, SW_SHOWMAXIMIZED);
    UpdateWindow(hWnd);

    MSG msg;

    while( GetMessage(&msg, NULL, 0, 0) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    //  Retorna msg.wParam

    return (int)msg.wParam;
}

/************************************************************************************************************************

    WndProc(hwnd, message, wParam, lParam)

************************************************************************************************************************/

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)

{
    static A a;
    static int i;

    switch ( message )
    {
        case WM_CREATE:
        {
            HDC hDC;
            if( !(hDC = GetDC(hwnd)) ) return -1;

            int iLogPixelsY = GetDeviceCaps(hDC, LOGPIXELSY);

            LOGFONT lf;
            memset(&lf, 0, sizeof(LOGFONT));
            lf.lfHeight = -MulDiv(11, iLogPixelsY, 72);
            wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Cambria Math");

            HFONT hFont;
            if( !(hFont = CreateFontIndirect(&lf)) ) goto FreeDC;

            hFont = (HFONT)SelectObject(hDC, hFont);

            int j = 5;
            i = j;

            A b(2);
            a = b;
            return 0;

            FreeDC: ReleaseDC(hwnd, hDC);
            return -1; 
        }
        break;

        case WM_DESTROY:

        PostQuitMessage(0);
        break;

        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

最佳答案

如果您使用 goto

b 的构造函数将不会被调用,但它仍在范围内。这在技术上是一个错误,尽管一些编译器只发出警告。

这是一个例子:

int main() {
  goto foo;
  int bar = 5;
  foo:
  ++bar; // doesn't work if goto is used - bar isn't initialized
}

看起来你似乎没有使用 b,但它的析构函数仍在被调用:

int main() {
  goto foo;
  A b;
  foo:
  b.~A(); // compiler silently adds destructor and other cleanup here
          // won't work if goto is used - b isn't initialized
}

关于c++ - C4533 警告 : why does goto skip variable initialization?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8101252/

相关文章:

c++ - 如何在 C/C++ 中检查字符串中的模式?

c++ - 如何开始编写智能指针?

c# - 将 SSL dll 导入项目

c++ - 如何将标准库与 C++ 模块一起使用? (例如 : `import std.io` )

c++ - 如何在 C++ 中将 int 连接到 wchar_t*?

c++ - 为重复字符打印星号的算法

c++ - getNthRoots函数错误答案

c++ - 模板 <typename T> 和模板 <class T> 有什么区别。对我来说,两者都产生相同的结果

c++ - 编写二进制文件 C++,强制某些内容位于字节 18 的方法?

c++ - strcpy() 在 Visual Studio 2012 中的行为