1

我的 CCS 6.1 ARM 编译器(用于 LM3Sxxxx Stellaris)抛出警告:

“MISRA 规则 12.2。在标准允许的任何评估顺序下,表达式的值应相同”

对于以下代码:

typedef struct {
  ...
  uint32_t bufferCnt;
  uint8_t buffer[100];
  ...
} DIAG_INTERFACE_T;

static DIAG_INTERFACE_T diagInterfaces[1];

...
DIAG_INTERFACE_T * diag = &diagInterfaces[0];
uint8_t data = 0;
diag->bufferCnt = 0;
diag->buffer[diag->bufferCnt++] = data; // line where warning is issued
...

我在我的代码中没有看到问题。是误报还是我的错误?

4

2 回答 2

4

放入diag->bufferCnt++单独的声明(正如汉斯在 OP 评论中所建议的那样),不应出现警告。

但是关于 MISRA 规则 12.2,我在您的程序中没有看到违反 12.2(您的语句中有一个序列点并且没有未指定的行为),我认为这是您的 MISRA 软件中的一个错误。

有关信息,MISRA 中还有一条建议性 12.13 规则说:

(MISRA-C:2004, 12.13)“增量 (++) 和减量 (--) 运算符不应与表达式中的其他运算符混合”

MISRA 的问题是它们的术语使用远非完美,对于 12.3,而->or=是 C 运算符,在解释中他们似乎只谈论算术运算符......

于 2015-09-13T22:01:20.503 回答
0

虽然您没有指明,但这是 MISRA-C:2004,规则 12.2,现在是 MISRA-C:2012 规则 13.2。正如 oauh 所说,这与“评估顺序”无关。

我强烈建议您参考 MISRA-C:2012,即使您需要符合 MISRA-C:2004,也可以使用 MISRA-C:2012,因为它已经阐明了许多指导方针,包括其他基本原理、解释和示例。

您不应该使用编译器来单独检查 MISRA-C 的兼容性,这很好,但编译器 #1 的目标不是警告您它致力于利用(优化)的语言的所有陷阱和陷阱。它们也不是很精确,就像在这种情况下一样。此外,翻译单元中有许多未定义的行为,编译器无法警告。最好也使用专用的 MISRA 静态分析工具,该工具不是特定于编译器的,但从 ISO C 标准的角度来看,它会警告所有不可预测的构造,而不是特定的实现。

正如 oauh 所说,这违反了 MISRA-C:Rule 12.13,现在 MISRA-C:2012 Rule 13.3 已放宽以允许 ++ 和 -- 与其他运算符混合,前提是 ++或 -- 是副作用的唯一来源(在您的情况下,赋值也是 C 术语中的副作用)。

该规则不是关键的,即其定义明确的行为,但前缀版本和后缀版本产生的不同值可能会导致混淆,因此它是“建议性的”,意味着不需要正式的偏差(再次,一个像样的 MISRA-C 工具将允许您抑制这种特定的违规行为)。

于 2015-09-14T00:38:05.053 回答