1

我正在重建一个应用程序以符合 MISRA 规则并使用 QA-C 来分析我的代码。

这些烦人的规则之一涉及指针和数组。你不能说:

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

bar[5] = 'a';

你也不能这样做:

*bar = 'a';
bar++;

我的问题涉及两个函数和一个文件范围变量。

最初此代码执行以下操作(类似于位伪代码):

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

我试图将其重写为以下内容:

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

但是随后 misra 和我的编译器(softune,由 Fujitsu)都抱怨。编译器说:

从 CHAR (*)[]' 分配不兼容的指针类型CHAR **' to:运算符 `='

米斯拉 说:

[C] 赋值的右操作数不是兼容的指针类型。导出到具有链接或更广泛范围的指针的自动对象的地址。

但是我确实需要能够在 foo_c 函数中索引一个数组。或者还有其他方法可以遵循 misra 并使我的代码正常工作。

如果我在同一个文件中执行以下操作:

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

然后,Misra 和我的编译器都没有抱怨任何事情。

4

5 回答 5

0

这对我来说没有意义:

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

我会这样:

static char *bufferPtr_new;
static int bufferIndex_new;

并用 bufferPtr_new[bufferIndex_new] 替换每个 *bufferPtr 但根据 MISRA 的说法,也许可以向我们解释当前代码有什么问题。

于 2012-07-03T14:19:46.847 回答
0

不知道你是否会喜欢这个:

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

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

希望能帮助到你。

于 2012-07-03T14:45:01.787 回答
0
static void foo_a(char * buffer /* other params */)

该参数buffer是一个指针,而不是一个数组,因此试图将其视为其他地方的数组将会失败。

明智的做法是foo_a接受指向数组的指针(char (*buffer)[N]对于某些 N)或指向struct包含适当大小数组的指针。然后,您可以将静态分配给文件char (*bufferPtr)[N]或(更好地)通过调用链传递数组指针。

于 2012-07-03T15:11:44.870 回答
0

这些烦人的规则之一涉及指针和数组。你不能说:....

char foo[10];

完全没问题,除了不允许的 char 类型。

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

如果 foo 是用数组语法声明的,那很好。如果 foo 使用指针语法声明它违反规则 17.4。请参阅下文对规则 17.4 的修复。此外,括号没有任何意义,无论是对于 MISRA 还是出于其他原因。

bar[5] = 'a';

完全没问题。

*bar = 'a';

完全没问题。

bar++;

规则 17.4 不允许这样做,该规则指出数组索引是唯一允许的指针算术形式。这确实是一个非常愚蠢的规则,我相信它会在下一个版本的 MISRA 中被删除。实际上,我曾经与委员会讨论过这条规则,除了化妆品之外,他们无法为这条规则提供任何理由。

解决方案是为该规则创建与 MISRA-C 的偏差,这就是大多数 MISRA 实现似乎所做的。不要只是盲目地遵循 MISRA。90% 的规则是好的,但也有一些奇怪的规则缺乏理由。

于 2012-07-04T11:23:30.657 回答
0

我已更改此代码的流程,只将缓冲区参数传递给每个后续版本。

它很丑陋,但它可以工作并且有点安全。“根据米斯拉”

于 2012-07-06T10:05:45.673 回答