2016-02-12 2 views
3

я заметил следующий код на Understanding Strict Aliasing:Что такое «ложный позитив»?

uint32_t 
swap_words(uint32_t arg) 
{ 
    U32*  in = (U32*)&arg; 
    uint16_t lo = in->u16[0]; 
    uint16_t hi = in->u16[1]; 

    in->u16[0] = hi; 
    in->u16[1] = lo; 

    return (in->u32); 
} 

По мнению автора,

выше источника при компиляции с GCC 4.0 с -Wstrict ступенчатости = 2 флаг включен воли сгенерировать предупреждение. Это предупреждение является примером ложных положительных. Этот тип литья разрешен и будет генерировать соответствующий код (см. Ниже). ясно зафиксировано, что -Wstrict-aliasing = 2 может возвращать false положительных результатов.

Интересно, что это ложноположительный, и я должен обратить на это внимание, когда сглаживание переменных?


Вот "соответствующий код (см ниже)" уже упоминалось выше, если оно соответствует:

Собран с -fstrict-aliasing -O3 -Wstrict-aliasing -std=c99 на версии GNU C 4.0.0 (Apple Computer, Inc. построить 5026) (PowerPC -apple-darwin8),

swap_words: 
    stw r3,24(r1) ; Store arg 
    lhz r0,24(r1) ; Load hi 
    lhz r2,26(r1) ; Load lo 
    sth r0,26(r1) ; Store result[1] = hi 
    sth r2,24(r1) ; Store result[0] = lo 
    lwz r3,24(r1) ; Load result 
    blr   ; Return 
+0

«Ложный положительный» - это причудливый способ сказать «ошибка инструмента». В этом случае ошибки компилятора, которые дают неверные диагностические сообщения. – Lundin

ответ

7

Здесь «ложное положительное» означает, что предупреждение неверно и что проблема на самом деле не существует. False positive - это стандартный термин в науке и медицине, обозначающий ошибку в процессе оценки, приводящую к mistaken detection of a condition tested. (A ложноотрицательный не будет выдавать предупреждение, если он подходит.)

Если вы уверены, что предупреждение ложно, вам не нужно исправлять код, чтобы удалить его. Возможно, вы захотите изменить структуру кода, чтобы избежать предупреждений о компиляции (или, по возможности, отключите предупреждение для этого раздела кода). Обычно без предупреждения компилятор гарантирует, что при появлении реального предупреждения, на которое вы должны обратить внимание, вы не пропустите его.

+1

Упрощен для правильной обработки предупреждений компилятора, изложенных в последнем абзаце. – DevSolar

+0

Согласно [этой странице в Википедии] (https://en.wikipedia.org/wiki/False_positives_and_false_negatives#False_positive_error), приведенное выше является фактически ложным отрицательным, а отрицательным является само предупреждение. Фальшивый позитив будет означать, что «этот код в порядке», когда он не является (для какого-либо другого кода). Это было очень запутанно. – unwind

+1

Ложноположительный - это правильный термин.Положительный результат означает, что некоторое состояние было обнаружено и сообщено неправильно. В этом случае условие «код не соответствует строжайшему правилу псевдонимов», и отчет является предупреждением. Фальшивый отрицательный результат будет не в состоянии обнаружить условие, которое присутствует, поэтому не сообщать об этом (или делать заявление отсутствует). – Peter

3

gcc использует специальную эвристику, чтобы найти проблемы со строгими правилами псевдонимов. Эти эвристики могут иметь неправильные срабатывания, ситуации, когда они сообщают о предупреждении, но ничего не сообщать.

3

false false в целом означает, что когда-либо притворяется, что ответ да/соответствует некоторому условию, когда на самом деле это неверно.

Итак, здесь gcc дает предупреждение о некорректном преобразовании из целого числа в структуру того же размера, содержащую два 16-разрядных целых числа, поскольку это опасная операция. Но вы знаете, что это действительно правильно и генерирует правильный код.

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