我怎样才能摆脱 QAC 警告?

How can I cast the expression to get rid of QAC warning?

我正在使用 QAC,我收到了以下针对相应源代码行的消息。我如何投射它才能让 QAC "understand" 它?

使用的编译器是 gcc - 它不会警告这个问题,因为它设置为 "iso c99"。

#define DIAGMGR_SIGNED_2_BYTES_178           ((s16)178)

sK  = (s16)(sE1 / DIAGMGR_SIGNED_2_BYTES_178);
                  ^

Result of signed division or remainder operation may be implementation defined

.

A division ('/') or remainder ('%') operation is being performed in a signed integer type and the result may be implementation-defined. Message 3103 is generated for an integer division or remainder operation in a signed type where:

  • One or both operands are non-constant and of signed integer type, or
  • Both operands are integer constant expressions, one of negative value and one of positive value

A signed integer division or remainder operation in which one operand is positive and the other is negative may be performed in one of two ways:

  • The division will round towards zero and any non-zero remainder will be a negative value
  • The division will round away from zero and any non-zero remainder will be a positive value In the ISO:C99 standard the first approach is always used. In the ISO:C90 standard either approach may be used - the result is implementation defined. For example:

/PRQA S 3120,3198,3408,3447 ++/

extern int r;

extern int si;

extern void foo(void)
{
    r = -7 / 4;     /* Message 3103 *//* Result is -1 in C99 but may be -2 in C90 */

    r = -7 % 4;     /* Message 3103 *//* Result is -3 in C99 but may be  1 in C90 */
    si = si / r;    /* Message 3103 */
}

您需要配置该工具,使其能够理解您的代码是 C99。在旧的 C90 标准中,负数除法可以用两种不同的方式实现,see this。这是 C90 标准中已知的 "bug",自 C99 以来已修复。

这是大多数静态分析工具的标准警告,尤其是当它们设置为检查 MISRA-C 合规性时。 MISRA-C:2004 和 2012 都要求程序员了解此 C 标准 "bug".


C90 中的解决方法:

如果您确定操作数不是负数,只需将它们转换为无符号类型,或使用无符号类型作为开头。

如果您知道操作数可能为负数:

  • 如果任一操作数为负数,则设置标志以指示它是哪一个。
  • 取两个操作数的绝对值。
  • 对绝对值进行除法。
  • 重新给数字加上符号。

不幸的是,这是 C90 中唯一的可移植解决方法。或者,您可以添加静态断言以防止代码在向下截断负数的系统上编译。

如果您使用的是 C99,则不需要变通方法,因为它总是截断为零。然后您可以安全地禁用警告。