Как да потискам грешките на 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. Бих искал глобално да премахна тези съобщения по отношение на използването на определени инициализатори, както е показано по-горе. Не мога да ги потискам глобално за всички ситуации, тъй като тези грешки могат да открият истински грешки в кода.


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 Това е добра точка. Виждал съм някои примери за използване на определен списък с инициализатори за инициализиране на вложени структури (като this), но не знам със сигурност дали това е правилният 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 на стандарта, нещото, предшестващо = в инициализатор, е списък-обозначител, който е последователност от един или повече обозначителиs. .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 отговориха, заявявайки, че „това изглежда е грешка“ и работят за коригирането й.

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 отговориха, че това изглежда е грешка и работят за коригирането й. Благодаря отново! - person embedded_guy; 12.07.2014

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

Но в случая на Jacchim Pileborg той просто излъчва 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, към които да се придържате, тъй като всичко е анонимно, вие ether трябва да поставите вградени команди изрично или чрез макрос.

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), така че не можете да потискате този екземпляр навсякъде. Сега можете да поставите в MACRO и след това да потиснете тези грешки за този символ. - person Simeon Pilgrim; 10.07.2014
comment
Заслужава си да се обмисли макро опцията. Въпреки че моят мениджър реши, че е неприемливо да има каквито и да било коментари за мъх в кодовата база, оттук и желанието за потискане в световен мащаб. Въпреки това може да успея да заобиколя това, като добавя -emacro(708, MY_UNION) към моя options.lnt файл. - person embedded_guy; 10.07.2014