Как подавить ошибки 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, чтобы глобально подавлять эти сообщения?

EDIT
Я должен был быть более подробным в отношении вопроса 2. Я хотел бы глобально подавить эти сообщения в отношении моего использования назначенных инициализаторов, как показано выше. Я не могу подавить их глобально для всех ситуаций, так как эти ошибки могут обнаруживать настоящие ошибки в коде.


person embedded_guy    schedule 02.04.2014    source источник
comment
Я не знаю, действительно ли вложение полей-членов (например, .bits.a) в порядке. Я подозреваю, что вам нужно сделать, например. My_value test[] = { { { .a = 2, .b = 3, .c = 2, .d = 3 } }, ... }.   -  person Some programmer dude    schedule 03.04.2014
comment
@JoachimPileborg Это хороший момент. Я видел несколько примеров использования назначенного списка инициализаторов для инициализации вложенных структур (например, это), но я точно не знаю, подходит ли это C99. Возможно, мне придется открыть еще один вопрос ...   -  person embedded_guy    schedule 03.04.2014
comment
Похоже, что мое использование назначенного списка инициализаторов, как написано выше, допустимо. Тем не менее, я все еще не могу заставить PC-Lint хорошо работать с этой конкретной реализацией.   -  person embedded_guy    schedule 11.04.2014
comment
Я согласен, что это действительно; грамматика допускает список-обозначений и .bits.a квалифицирует (и gcc, и clang принимают его). Но что произойдет, если вы переместите .bits на уровень выше?   -  person Keith Thompson    schedule 10.07.2014
comment
@KeithThompson, похоже, ты что-то понял. Если я перейду на [0].bits.a = 1 и продолжу через [1].bits.d = 0, PC-Lint больше не будет жаловаться, и armcc по-прежнему правильно компилирует его. Это может быть мой лучший вариант.   -  person embedded_guy    schedule 10.07.2014


Ответы (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 Software ответили, что «похоже, это ошибка», и работают над ее исправлением.

person Keith Thompson    schedule 10.07.2014
comment
PC-Lint 9.00k не имеет проблем со второй формой, опубликованной выше. Я бы пошел с этим. - person Simeon Pilgrim; 10.07.2014
comment
Точно, я только что проверил с 8.00x, и PC-Lint доволен, и он по-прежнему передает исходное намерение кода. Спасибо, Кит, и спасибо @SimeonPilgrim за то, что вдохнули новую жизнь в вопрос, который, как я думал, останется без ответа. - person embedded_guy; 10.07.2014
comment
@SimeonPilgrim и Кит, хорошие люди из Gimpel Software ответили, что это ошибка, и работают над ее исправлением. Спасибо еще раз! - person embedded_guy; 12.07.2014

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

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

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

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

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 придерживались, поскольку все это анонимно, вам приходится вставлять встроенные команды явно или с помощью макроса.

person Simeon Pilgrim    schedule 09.07.2014
comment
Спасибо, Симеон. Я полагаю, что мне следовало более подробно остановиться на вопросе номер 2. Я хотел бы скрыть эти сообщения в глобальном масштабе, поскольку они применимы к данной конкретной ситуации. Однако обе эти ошибки могут быть потенциально полезными, поэтому я не хочу, чтобы они отключались для всех ситуаций. Интересно, что 9.00k не любит @JoachimPileBorg и мои инициализации... Любой из них должен работать под C99. +1 - person embedded_guy; 09.07.2014
comment
@embedded_guy 9.00k не жалуется на это как на плохое, но у него есть info 708, который было бы безопаснее подавлять или подавлять файл за файлом. Настоящая проблема заключается в том, что то, что вы делаете, на самом деле не является классом вещей (кроме инициализации союза 708), поэтому вы не можете подавить этот экземпляр везде. Теперь вы можете поместить в МАКРОС, а затем подавить эти ошибки для этого символа. - person Simeon Pilgrim; 10.07.2014
comment
Вариант макроса стоит рассмотреть. Хотя мой менеджер решил, что недопустимо наличие каких-либо lint-комментариев в кодовой базе, отсюда и желание подавить глобально. Однако я могу обойти это, добавив -emacro(708, MY_UNION) в свой файл options.lnt. - person embedded_guy; 10.07.2014