Domanda

I am rebuilding an application to comply with MISRA-rules and using QA-C to analyze my code.

One of those annoying rules involve pointers and arrays. You can't say:

char foo[10];
char * bar = &(foo[0]);

bar[5] = 'a';

Nor can you then do:

*bar = 'a';
bar++;

My problem involves two functions and a file-scope variable.

Originally this code did the following (bit-pseudocode-like):

static char * bufferPtr;

static void foo_a(char * buffer /* other params */)
{
    bufferPtr = buffer;

    /* some logic goes here */
    switch()
    {
        case 'b':
           foo_b(/* some param */);
}

static void foo_b(/* parameters */)
{
    if (/*something*/)
    {
        /*  some logic */
        foo_c(/* data-param */);
        /* some logic */
    }
    else
    {
        /*  some logic */
        foo_c(/* data-param */);
        /* some logic */
    }
}

static void foo_c(char data)
{
    *buffer++ = data;
}

I've tried to rewrite it to the following:

static char (*bufferPtr)[];
static char bufferIndex;

static void foo_a(char buffer[] /* other params */)
{
    bufferPtr = &buffer;
    bufferIndex = 0;

    /* same */
}

static void foo_b(/* parameters */)
{
    /* same */
}

static void foo_c(char data)
{
    (*bufferPtr)[bufferIndex] = data;
    bufferIndex++;
}

But then both misra and my compiler (softune, by Fujitsu) complain. Compiler says:

assignment incompatible pointer types from CHAR **' toCHAR (*)[]': operator `='

Misra says:

[C] Right operand of assignment is not of compatible pointer type. Address of automatic object exported to a pointer with linkage or wider scope.

However I do need to be able to index an array in the foo_c function. Or are there other ways to and follow misra and make my code work.

If I do the following in the same file:

static CHAR foo[10];
static CHAR (*bar)[];
static void f(void)
{
    bar = &foo;
}

Then nor Misra nor my compiler complain about anything.

È stato utile?

Soluzione 5

I've changed the flow of this code to just pass the buffer parameter to each subsequent version.

It is ugly, but it works and is somewhat safe. 'according to misra'

Altri suggerimenti

This doesn't make sense to me:

static char (*bufferPtr)[];
static char bufferIndex;

I'd make it like that:

static char *bufferPtr_new;
static int bufferIndex_new;

And replace every *bufferPtr with bufferPtr_new[bufferIndex_new] But perhaps explain to us what's wrong with current code, according to MISRA.

Not sure if you're going to like this:

static char *(bufferPtr[10]); /* must have a size */
static char bufferIndex;

static void foo_a(char buffer[])
{
    *bufferPtr = buffer;
    bufferIndex = 0;
    /* etc */ 
}

Hope it helps.

static void foo_a(char * buffer /* other params */)

The argument buffer is a pointer, not an array, so trying to treat it as an array elsewhere is going to fail.

The sensible thing would be to have foo_a accept a pointer to an array (char (*buffer)[N] for some N) or a pointer to a struct containing an appropriate sized array. You can then assign to a file static char (*bufferPtr)[N] or (better) pass the array pointer through your call chain.

One of those annoying rules involve pointers and arrays. You can't say: ....

char foo[10];

Perfectly fine, except for the char type which isn't allowed.

char * bar = &(foo[0]);

Fine if foo is declared with array syntax. If foo was declared using pointer syntax it violates rule 17.4. See the fix for rule 17.4 further below. Also, the parenthesis doesn't make any sense whatsoever, neither for MISRA nor for other reasons.

bar[5] = 'a';

Perfectly fine.

*bar = 'a';

Perfectly fine.

bar++;

This isn't allowed by rule 17.4, which is stating that array indexing is the only allowed form of pointer arithmetic. It is indeed a very dumb rule and I believe it will be removed in the next version of MISRA. I actually once addressed this rule with the committee and they couldn't give any rationale for the rule other than cosmetics.

The solution is to create a deviation from MISRA-C for this rule, that's what most MISRA-implementations seem to do. Don't just blindly follow MISRA. 90% of the rules are good, but there are some odd ones lacking a rationale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top