Этот шаблон работает в 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 не буду.

Другие вопросы по тегам