Этот шаблон работает в C++?
Я выполняю статический анализ кода 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 (условие) {выражение-блок = время жизни переменной условия}.
VS счастливо скомпилировал (и предположительно запустил это) в течение достаточно долгого времени. У меня не было ни одного пошагового кода, подобного этому, в течение долгого времени, но, насколько я могу судить, он только входит в блок if, если оператор select_image bool() возвращает true, и уничтожает экземпляр select_image при выходе из блока if.
PREfast не так? Или здесь есть что-то тонкое, что делает мой код и предположения неверными?
1 ответ
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
не буду.