Question

I am using PC-Lint 8.00x with the following options:

+v -wlib(1) +fan +fas

I receive a number of error messages from PC-Lint when I run code similar to the following:

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;
}

The reported errors are defined by PC-Lint as follows:

Error 133: Too many initializers for aggregate 'unknown-name'

Error 10: Expecting '}'

I have tried searching Gimpel and have done some Google searches, but I cannot find anything useful. The code functions as intended and everything initializes properly. Here are my questions.

1. Does PC-Lint 8.00x support C99 style initialization of structure members?

2. If so, what options/flags do I have to set for PC-Lint to suppress these messages globally?

EDIT
I should have been more detailed in regards to question 2. I would like to globally suppress these messages in regards to my usage of designated initializers as shown above. I cannot suppress them globally for all situations as these errors can detect true errors in the code.

Was it helpful?

Solution

As far as I can tell, this syntax:

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,
    },
};

is valid in C99 (and C11). Looking in section 6.7.8 of the standard, the thing preceding the = in an initializer is a designator-list, which is a sequence of one or more designators. .bits.a is valid in that context.

Apparently PC-Lint doesn't support that syntax. (You might want to notify the maintainers, unless it's already supported in a later version.)

As a workaround, if you change it to this:

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

it's still valid C (and arguably clearer) and, based on what you just wrote in a comment, PC-Lint accepts it.

(If you want to be even more explicit, you might consider adding [0] = and [1] = designators.)

UPDATE : QUoting a new commment:

The good people at Gimpel software have responded stating that "this appears to be a bug" and are working to correct it.

OTHER TIPS

Not sure to the C99 and 8.00x support question, as I have 9.00k installed. But 9.00k dislikes your form of union initialization, but Visual Studio has no issue.

But for Jacchim Pileborg's case it just emits a Info 708: union initialization while might be safer to turn off.

As noted in the comments you dont want to fully globally remove these error types, so -e133 and -e10 will not solve your problems.

So using Joachim's form, I can using a macro suppress it like so:

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;
}

Ugly, but as you have nothing to make the lint commands to stick to as it's all anonymous, you ether have to put inline commands explicitly or via a macro.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top