我正在重建一个符合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和我的编译器(softits,由Fujitsu)抱怨。 编译说:
从
CHAR **' to
CHAR(*)[]'赋值不兼容的指针类型:operator` ='
米斯拉说:
[C]赋值的右操作数不兼容指针类型。 导出到具有链接或更宽范围的指针的自动对象的地址。
但是我确实需要能够在foo_c函数中索引数组。或者是否有其他方法来遵循misra并使我的代码有效。
如果我在同一个文件中执行以下操作:
static CHAR foo[10];
static CHAR (*bar)[];
static void f(void)
{
bar = &foo;
}
然后,Misra和我的编译器都没有抱怨任何事情。
答案 0 :(得分:0)
这对我来说没有意义:
static char (*bufferPtr)[];
static char bufferIndex;
我会这样做:
static char *bufferPtr_new;
static int bufferIndex_new;
用bufferPtr_new替换每个* bufferPtr [bufferIndex_new] 但根据MISRA的说法,也许向我们解释当前代码有什么问题。
答案 1 :(得分:0)
不确定你是否会喜欢这个:
static char *(bufferPtr[10]); /* must have a size */
static char bufferIndex;
static void foo_a(char buffer[])
{
*bufferPtr = buffer;
bufferIndex = 0;
/* etc */
}
希望它有所帮助。
答案 2 :(得分:0)
static void foo_a(char * buffer /* other params */)
参数buffer
是一个指针,而不是一个数组,因此尝试将其视为其他地方的数组将会失败。
明智的做法是让foo_a
接受指向数组的指针(某些N为char (*buffer)[N]
)或指向包含适当大小数组的struct
的指针。然后,您可以将文件分配给静态char (*bufferPtr)[N]
或(更好)通过调用链传递数组指针。
答案 3 :(得分:0)
其中一个恼人的规则涉及指针和数组。你不能说:....
char foo[10];
非常好,除了不允许的字符类型。
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%的规则都很好,但有些奇怪的规则缺乏理由。
答案 4 :(得分:0)
我已将此代码的流程更改为仅将缓冲区参数传递给每个后续版本。
它很难看,但它有效并且有些安全。 '根据misra'