1

我将 MACRO#define用于不同的数据类型,如下所示。

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

无论我在哪里使用这些MACROs.

在 typedef 之外使用修饰符或类型“无符号”[MISRA 2012 Directive 4.6,咨询]

在 typedef 之外使用修饰符或类型“短”[MISRA 2012 Directive 4.6,咨询]

在 typedef 之外使用修饰符或类型“long”[MISRA 2012 Directive 4.6,咨询]

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

在 typedef 之外使用修饰符或类型“_Bool”[MISRA 2012 Directive 4.6,咨询]

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

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

4

2 回答 2

2

规则 4.6 说您应该使用类型来表示大小和签名,例如stdint.h类型,而不是默认值unsigned int等。

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

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

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

于 2019-08-26T07:42:56.167 回答
2

但是,除了禁用此规则之外,还有其他方法可以消除这些警告。

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


使用 a#define而不是 atypedef是不好的做法。使用的主要优点之一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),静态分析工具会准确地处理这些内容,并生成相应的消息。

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

于 2019-08-26T08:10:00.933 回答