2012-05-14 2 views
0

Прежде всего, это похоже на: How are integer types converted implicitly?, но с другим предупреждением MISRA.Правило 10.1 и перечисления MISRA

Компилятор не генерирует ошибку MISRA, но инструмент статического анализа делает это. У меня есть билет с производителем инструмента.

Дано:

#include <stdio.h> 
enum Color {RED, VIOLET, BLUE, GREEN, YELLOW, ORANGE}; 

int main(void) 
{ 
    enum Color my_color; 
    my_color = BLUE; 
    if (my_color == YELLOW) // Generates MISRA violation, see below. 
    { 
    printf("Color is yellow.\n"); 
    } 
    else 
    { 
    printf("Color is not yellow.\n"); 
    } 
    return 0; 
} 

Статический инструмент анализа генерирует нарушение Мишра для if заявления:

MISRA-2004 Rule 10.1 violation: implicitly changing the signedness of an expression. 
Converting "4", with underlying type "char" (8 bits, signed), 
to type "unsigned int" (32 bits, unsigned) with different signedness. 

Является ли компилятор правильно (не идентифицировать дефект) или статический инструмент анализа?

+0

же код, та же ошибка, отчет об ошибке только немного больше подробный. Я не вижу разницы между вашими фрагментами кода. – Mat

+0

Мне было бы интересно узнать, какой ответ вы получили от своего поставщика инструмента, но похоже, что инструмент сломан. – Andrew

ответ

4

Per спецификации языка C, тип выражения:

typedef enum Colors {RED, VIOLET, BLUE, GREEN, YELLOW, ORANGE} Colors_t; 

является signed int.

Также, согласно языку, значение перечислимого элемента является наименьшей единицей, которая может содержать всю нумерацию. Таким образом, в приведенном выше перечислении BLUE имеет тип signed char.

статические средства анализа сообщают о нарушении Мишра, когда переменная Colors_t сравнивается с BLUE:

Colors_t my_color; 
if (my_color == BLUE) // This generates a MISRA violation. 

Нарушение является signed int по сравнению с signed char.

Кроме того, элементы перечисления могут быть смешаны с другими типами перечисления без ошибок, поскольку перечислений не единственный тип:

typedef enum Tree_Species {REDWOOD, CYPRUS, PALM, OAK, JUNIPER, SEGUARO} Tree_Species_t; 
Tree_Species_t my_tree; 
my_tree = BLUE; 
0

Похоже, что кто-то (ваш компилятор или статический инструмент) считает, что ваше перечисление не совпадает с размером и/или подписью как int.

У компилятора My Green Hills есть опция --short-enum (используйте наименьший тип для Enum), который выберет char для вашего примера выше. Есть ли у вашего компилятора такой вариант? Включено ли это? По умолчанию ли компилятор перечисляет значение «нестандартное»?

По моему опыту, по умолчанию статические инструменты по умолчанию отлично соответствуют спецификациям языка, что означает, что он должен ожидать, что перечисление будет иметь размер int. (См. Эту ссылку для справки: What is the size of an enum in C?). Поскольку большинство статических инструментов отслеживают использование вашей командной строки компилятора, ваши параметры времени компиляции могут убеждать статический анализатор, что ваши перечисления меньше ints.

Я предлагаю тщательно проанализировать документацию вашего компилятора и статического анализатора для разрешения конфликта. Следите также за процессом сборки (параметры времени компиляции, значения по умолчанию и т. Д.).

-1

Это, вероятно, в результате провозглашения my_color

enum Color my_color; 

Пробуйте удалить «перечисление» из этого:

Color my_color; 

Статический анализатор, вероятно, считает, что вы объявляете отдельное перечисление, таким образом, нарушение 10.1. Поскольку в этом случае другой тип, правило MISRA запрещает присваивать один тип другому.

+2

-1 А? Это C, а не C++. После 'enum Color {A, B, C};' не существует типа с именем 'Color' (как я полагаю, на C++). – pmg

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