2016-06-28 15 views
2

Я побежал статический анализ кода для MISRA 2004 и MISRA 2012 на следующий код C:Обе стороны имеют побочные эффекты?

BOOL_TYPE Strings_Are_Equal(const char *s1, const char *s2) 
{ 
    BOOL_TYPE result = True; 
    const char *str1 = s1; 
    const char *str2 = s2; 

    if (NULL == s1 || NULL == s2) 
    { 
    result = False; 
    } 
    else if (strlen(s1) != strlen(s2)) 
    { 
    result = False; 
    } 
    else 
    { 
    while (*str1 != 0) 
    { 
     if(tolower(*str1++) != tolower(*str2++)) 
     { 
     result = False; 
     break; 
     } 
    } 
    } 

    return result; 
} 

и получили следующие результаты из отчетов PC-Lint: enter image description here

Может кто-нибудь объяснить, как это код в строке 58 и 66 страдает от побочных эффектов и как мне его исправить?

ответ

6

Вызов функции может вызвать побочный эффект при использовании формального определения стандарта C.

В конкретном случае strlen(s1) != strlen(s2) в этих функциях нет ничего, что могло бы нанести вред. Нецелесообразно реализовать их, например, внутренние переменные static. Но если бы присутствовали такие внутренние переменные, порядок оценки мог давать разные результаты в зависимости от того, какой вызов функции был выполнен первым. Вероятно, это является поводом для предупреждения.

В случае tolower(*str1++) != tolower(*str2++) есть два побочных эффекта вызова функции и два побочных эффекта с переменным назначением от операторов ++, всего 4 в одном выражении. Несмотря на то, что этот конкретный случай безопасен, такой код опасен, так как он может зависеть от порядка оценки или даже оказаться совсем нелогичным (например, i=i++;), что было бы серьезной ошибкой.

Решите это, сохранив результаты функции во временных переменных. И никогда не смешивайте ++ с другими операторами, потому что это так опасно, бессмысленно и запрещено другим правилом MISRA:

MISRA-C: 2004 Правило 12,13

приращение (++) и декремента (-) операторам не следует смешивать с другими операторами в выражении.

+0

Правильный ответ imo. Я дал вам взнос, так как вы указали, что я забыл вначале. (Должно быть, это было дисквалификацией) – 2501

+0

Причина голосования? Отсутствие котировок по правилам MISRA и стандарту C? Я не могу найти никаких ошибок в ответе. – Lundin

1

В качестве дополнения к отличным ответ Лундин, в податливый подход MISRA будет:

while (*str1 != 0) 
    { 
     // Condition should be a single sequence point 
     // ... with no side effects 
     if (tolower(*str1) != tolower(*str2)) 
     { 
     result = false; 
     break; 
     } 

     // Now increment pointers 
     *str1++; 
     *str2++; 
    } 

Таким образом, у вас есть четкое различие между вашими точками последовательности.