Я выполняю статический анализ кода PREfast для наших проектов, и он выдает мне C6001 «использование неинициализированной памяти» для этого шаблона:
// AutoSelectGDIObject is a class
if (AutoSelectGDIObject & select_image = AutoSelectGDIObject(hDCImgSource, hBmp))
{
// use hDCImgSource knowing that hBmp is selected into it
}
// now we are guaranteed that hDCImgSource has had hBmp removed and its previous bmp re-selected into itself
Хитрость, которую я пытаюсь использовать, заключается в том, чтобы область действия select_image была доступна только для выражения if (т.е. if (условие) {expression-block = время жизни переменной условия}.
VS счастливо скомпилировал (и предположительно запустил это) в течение достаточно долгого времени. У меня не было ни одного пошагового кода, подобного этому, в течение длительного времени, но, насколько я могу судить, он только входит в блок if, если оператор select_image bool () возвращает true, и уничтожает экземпляр select_image при выходе из блока if.
PREfast не так? Или здесь есть что-то тонкое, что делает мой код и предположения неверными?
PREfast не так? Или здесь есть что-то тонкое, что делает мой код и предположения неверными?
Этот код недопустим в C ++, но VC компилирует его, потому что он позволяет в качестве документированного расширения связывать ссылки lvalue с не const
Квалифицированные типы к временным.
Это глупое продолжение, на мой взгляд. Согласно стандарту C ++, временные ссылки могут быть связаны только с lvalue ссылками на const
или для оценки ссылок (и в этом случае их время жизни продлевается до конца полного выражения, которое их создает).
Поэтому ваш if
Заявление должно быть:
if (AutoSelectGDIObject const& select_image =
// ^^^^^
AutoSelectGDIObject(hDCImgSource, hBmp))
Смотрите, например, это живой пример.
Обратите внимание, однако, что вам не нужно использовать ссылки вообще здесь. Другими словами, следующее if
Заявление также является действительным и лучше выражает ваше намерение, чем создание временной привязки к lvalue-ссылке на const
:
if (AutoSelectGDIObject select_image = AutoSelectGDIObject(hDCImgSource, hBmp))
Смотрите, например, это живой пример. Кроме того, вышеизложенное также позволит вам модифицировать select_image
При этом ссылка на const
не буду.
Других решений пока нет …