在 typedef 之外使用修饰符或类型 'unsigned' [MISRA 2012 指令 4.6,建议]

Use of modifier or type 'unsigned' outside of a typedef [MISRA 2012 Directive 4.6, advisory]

我正在为不同的数据类型使用 MACRO #define,如下所示。

#define CCP_BYTE    unsigned char
#define CCP_WORD    unsigned short
#define CCP_DWORD   unsigned long

在我使用这些 MACROs 的许多语句(数量为 146)中观察到以下警告。

Use of modifier or type 'unsigned' outside of a typedef [MISRA 2012 Directive 4.6, advisory]

Use of modifier or type 'short' outside of a typedef [MISRA 2012 Directive 4.6, advisory]

Use of modifier or type 'long' outside of a typedef [MISRA 2012 Directive 4.6, advisory]

在所有实例中观察到警告,无论我在 if 语句中对测试条件进行类型转换,如下所示。

Use of modifier or type '_Bool' outside of a typedef [MISRA 2012 Directive 4.6, advisory]

if( !(bool) ChkStatus)
{
  /* execute if satisfy */    
}

我提到了 ,其中讨论了 bool 类型的查询。但是,除了禁用此规则以消除这些警告之外,还有其他方法吗?

规则 4.6 说你应该使用大小和符号类型,例如 stdint.h 类型,而不是默认的 unsigned int

意味着如果您坚持使用 C90,则可以创建自己的自定义 typedef。否则你应该使用 stdint.h。这反过来意味着您的工具将只允许 unsigned int 等连同 typedef,而不允许连同 #define

如前所述,关于 bool 的评论是误报。显然这是 Lint 中的一个工具错误,工具供应商已根据链接问题 .

中的评论确认了这一点

MISRA-C 要求使用一种布尔类型,但没有命名。可能您必须配置静态分析器,以便它知道所使用的 bool 类型的名称。就 MISRA 而言,使用 _Boolbool 甚至自定义类型都可以。

However, Is there any way other than disabling this rule to get rid of these warnings.

这绝对是错误的做法。你应该解决问题,而不是隐藏消息。


使用 #define 而不是 typedef 是不好的做法。使用 typedef 的主要优点之一是可以在编译时正确检查类型。

想象一下:

#define LENGTH int
#define MASS int

typedef int tLength
typedef int tMass

现在很明显,类型为 tLength 和 tMass 的两个变量将具有不同的类型。但是定义为 LENGTH 和 MASS 的两个变量将具有相同的类型 (int)。

从 tLength 到 tMass 的类型转换(例如)可能至少会引发警告,因为长度和质量不兼容,但从 LENGTH 到 MASS 的转换将不会被检测到。


有(我现在无法访问文档)并且可能仍然有一条 MISRA 规则规定禁止依赖随编译器提供的任何代码(包括标准库)。

这意味着您必须自己定义/编写所有内容。


备注

现代编译器添加了越来越多的静态分析功能。然而:

  • 这些能力很多时候都非常有限;
  • 默认情况下这些功能往往被禁用。

即使启用所有静态分析,编译器本身也可能检测不到某些东西(例如上面的 tLength 和 tMass 之间的差异)。

但是,(尤其是我们在 pc-lint 的上下文中),静态分析工具 准确地 寻找那些东西,并生成相应的消息。

底线:要拥有 "the safest" 程序,您需要使用最佳编码实践,以帮助静态分析工具发挥最佳作用。 (请注意:只有最佳实践和静态分析并不能保证完美的程序 = 因此引号)