2013-04-17 5 views
2

Я бегу PreFast статический анализ кода на моих наших проектов, и это дает мне C6001 «с использованием неинициализированные памяти» ошибки для этой модели:Работает ли этот шаблон на C++?

// 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 

Хитрость Я пытаюсь использовать это, чтобы позволить (if) (0)

VS счастливо скомпилирован (и предположительно запускает это) в течение некоторого времени. У меня нет ни одного так как это довольно долгое время, но, насколько я могу судить, он входит только в блок if, если оператор select_image bool() возвращает true, и он уничтожает экземпляр select_image после выхода из i f блок.

Является ли PREfast неправильным? Или здесь что-то тонкое, что делает мой вышеприведенный код и допущения неправильными?

+0

Does 'AutoSelectGDIObejct()' возвращает ссылку? –

+0

'AutoSelectGDIObejct' - это класс. Я использую ссылку, чтобы обойти тот факт, что C++ не позволит мне просто использовать 'if (AutoSelectGDIObject select_image (...))' <- не компилируется :( – Mordachai

+0

Это не должно. причина: http://stackoverflow.com/questions/15580903/scope-of-an-inside-parenthesis-declared-object –

ответ

4

Является ли PREfast неправильным? Или здесь что-то тонкое, что делает мой вышеприведенный код и допущения неправильными?

Этот код недействителен C++, но VC компилирует его, потому что он позволяет, как документально расширение, связывание Lvalue ссылки, не являющихся const -qualified типов на временных.

Это глупое расширение, на мой взгляд. Согласно стандарту C++, временные ссылки могут привязываться только к значениям lvalue до const или к rvalue-ссылкам (и в этом случае их время жизни увеличивается за пределами полного выражения, которое их создает).

Таким образом, ваше if заявление должно быть:

if (AutoSelectGDIObject const& select_image = 
//      ^^^^^ 
           AutoSelectGDIObject(hDCImgSource, hBmp)) 

См, например, это live example.

Обратите внимание, что вам не нужно использовать ссылки. Другими словами, следующий if утверждение справедливо и выражает ваше намерение лучше, чем создание временной границы с ссылкой на Lvalue const:

if (AutoSelectGDIObject select_image = AutoSelectGDIObject(hDCImgSource, hBmp)) 

См, например, это live example. Кроме того, вышесказанное также позволит вам изменитьselect_image, в то время как ссылка на const не будет.

+0

AutoSelectGDIObject, похоже, является именем класса здесь. – mfontanini

+0

Хорошо - полезно знать. И с изменением на const & вы говорите, что код действителен (т. е. что if -condition будет eval для истинного IFF select_image.operator bool() верно?) – Mordachai

+0

@Mordachai: Это действительно, да. См., например, [этот пример] (http://ideone.com/MU2q6w). –

Смежные вопросы