Как подавить ошибки PC-Lint для инициализации элементов структуры в стиле C99?

Я использую PC-Lint 8.00x со следующими опциями:

+v -wlib(1) +fan +fas

Я получаю несколько сообщений об ошибках от PC-Lint, когда запускаю код, подобный следующему:

typedef union
{
    struct
    {
        unsigned int a : 4;
        unsigned int b : 4;
        unsigned int c : 4;
        unsigned int d : 4;
    } bits;
    unsigned short value;
} My_Value;

int main (void)
{
    My_Value test[] =
    {
        {
            .bits.a = 2,
            .bits.b = 3,    //Errors 133 and 10
            .bits.c = 2,
            .bits.d = 3,
        },
        {
            .bits.a = 1,
            .bits.b = 1,    //Errors 133 and 10
            .bits.c = 1,
            .bits.d = 0,
        },
    };

    /* Do something meaningful. */

    return 0;
}

Сообщенные ошибки определяются PC-Lint следующим образом:

Ошибка 133: слишком много инициализаторов для совокупного "неизвестного имени"

Ошибка 10: ожидание '}'

Я попытался найти Gimpel и сделал несколько поисков в Google, но не могу найти ничего полезного. Код работает так, как задумано, и все правильно инициализируется. Вот мои вопросы.

1. Поддерживает ли PC-Lint 8.00x инициализацию элементов структуры в стиле C99?

2. Если да, какие опции / флаги мне нужно установить для PC-Lint, чтобы подавлять эти сообщения глобально?

РЕДАКТИРОВАТЬ
Я должен был быть более подробным в отношении вопроса 2. Я хотел бы глобально подавить эти сообщения в отношении моего использования назначенных инициализаторов, как показано выше. Я не могу подавить их глобально для всех ситуаций, поскольку эти ошибки могут обнаружить истинные ошибки в коде.

2 ответа

Решение

Насколько я могу сказать, этот синтаксис:

My_Value test[] =
{
    {
        .bits.a = 2,
        .bits.b = 3,
        .bits.c = 2,
        .bits.d = 3,
    },
    {
        .bits.a = 1,
        .bits.b = 1,
        .bits.c = 1,
        .bits.d = 0,
    },
};

действует в C99 (и C11). Глядя в раздел 6.7.8 стандарта, вещь, предшествующая = в инициализаторе находится список указателей, который представляет собой последовательность одного или нескольких указателей. .bits.a действует в этом контексте.

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

В качестве обходного пути, если вы измените его на это:

My_Value test[] =
{   
    { .bits =
        {   
            .a = 2,
            .b = 3,
            .c = 2,
            .d = 3,
        },
    },
    { .bits =
        {   
            .a = 1,
            .b = 1,
            .c = 1,
            .d = 0,
        },
    },
};

это все еще действительный C (и, возможно, более ясный), и, основываясь на том, что вы только что написали в комментарии, PC-Lint принимает это.

(Если вы хотите быть еще более явным, вы можете рассмотреть возможность добавления [0] = а также [1] = десигнаторами.)

ОБНОВЛЕНИЕ: Цитирование нового комментария:

Хорошие люди в программном обеспечении Gimpel ответили, что "это похоже на ошибку", и работают над ее устранением.

Не уверен в вопросе поддержки C99 и 8.00x, так как у меня установлено 9.00k. Но 9.00k не нравится ваша форма инициализации объединения, но Visual Studio не имеет проблем.

Но для случая Яхима Пилеборга это просто испускает Info 708: union initialization хотя может быть безопаснее выключить.

Как отмечено в комментариях, вы не хотите полностью глобально удалять эти типы ошибок, поэтому -e133 а также -e10 не решит ваши проблемы.

Таким образом, используя форму Joachim, я могу использовать макрос подавить его следующим образом:

typedef union
{
    struct
    {
        unsigned int a : 4;
        unsigned int b : 4;
        unsigned int c : 4;
        unsigned int d : 4;
    } bits;
    unsigned short value;
} My_Value;

#define MY_UNION(A,B,C,D) /*lint -save -e708*/{{.a=(A),.b=(B),.c=(C),.d=(D)}}/*lint -restore*/

int main(void)
{
    My_Value test[] =
    {
        MY_UNION(2, 3, 2, 1),
        MY_UNION(1, 2, 3, 4)
    };

    return 0;
}

Ужасно, но так как вам нечего делать командами lint, так как все это анонимно, вы должны вводить встроенные команды явно или с помощью макроса.

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