问题描述
我得到:
但是如果代码得到 FreeDC
中的标签 WM_CREATE
,' b
'未初始化。如果在这种情况下没有初始化,它如何可以跳过它的初始化。我只是不明白警告。
But if the code gets to the label FreeDC
in WM_CREATE
, 'b
' is not initialized. How its initialization could be skiped, if it is not initialized in that situation. I just don't understand the warning.
#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
跳过的合适的局部范围:
You could avoid the problem by introducing a suitable local scope that gets skipped by the goto
:
HFONT hFont;
if( !(hFont = CreateFontIndirect(&lf)) )
{
goto FreeDC;
}
hFont = (HFONT)SelectObject(hDC, hFont);
{ // new scope; skipped entirely by goto
int j = 5;
i = j;
A b;
a = b(2);
}
return 0;
FreeDC:
ReleaseDC(hwnd, hDC);
return -1;
如果你仔细考虑C ++和范围以及自动对象生命周期, goto
真的会对整个编程模型造成严重破坏。这就是为什么有许多(通常静默隐含)条件,你可以去,而不是。一般来说,如果范围包含新的自动变量,跳到范围的中间是有问题的。我们通过引入一个新的局部范围避免这种情况, goto
跳过完全跳过。
If you think about C++ and scopes and automatic object lifetimes really carefully, you'll come to conclude that goto
really wreaks havoc with the entire programming model. That's why there are many (often quietly implied) conditions on where you can go-to and wher not. Generally, jumping into the middle of a scope is problematic if the scope contains new automatic variables. We avoid this by introducing a new, local scope that the goto
jump skips entirely.
这篇关于C4533警告:为什么goto跳过变量初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!