前言
近期需要再次测一下代码,相比以前测试更有经验,也做了比较多的记录,正好将经验通过博客保留下来,为以后可能的QAC测试做准备。
安装导入分析代码
这部分在上一篇中已经详细介绍,具体请见,如有疑问可以留言。
【回眸】QAC软件指南——萌新使用篇http://t.csdnimg.cn/S6Zpe
前置经验
以前的导入头文件我选择提取全部头文件在一个文件夹里然后导入单个文件夹完成所有头文件的导入,但近期热心同事拿出shell脚本自动化添加头文件,从此找不到头文件的问题再也没出现,不仅如此,400多个头文件的路径在2分钟内就被水灵灵地加上了,实属科技改变生活。
QAC报错分析
根据同系列前一篇文章分析代码后,完成代码分析之后就进入了分析纠错环节
下面记录本次分析代码遇到的问题
app.c
1. 实在找不到原因,只好 disable
2.不允许多行注释
3.在#include "..."指令中使用的文件名不符合ISO:C90标准最严格的可移植性要求。为了达到这种严格的一致性,包含文件名必须限制在最多6个字母字符、一个句点(.)和一个字母字符。这些字符应该全部大写或全部小写。
4.消息0857指出了一种情况,即在翻译单元内定义的宏数量超过了ISO:C90标准的最低要求1024个。消息0380指出了违反相应ISO:C99限制的代码,即4095个宏。
bootchain_handler.c
1.在#include "..."指令中使用的文件名不符合ISO:C90标准最严格的可移植性要求。为了达到这种严格的一致性,包含文件名必须限制在最多6个字母字符、一个句点(.)和一个字母字符。这些字符应该全部大写或全部小写。
2.消息0857指出了一种情况,即在翻译单元内定义的宏数量超过了ISO:C90标准的最低要求1024个。消息0380指出了违反相应ISO:C99限制的代码,即4095个宏。
chagen.c
1.在注释里有特殊字符@,不符合规则.
2.不允许多行注释
3.不允许在头文件路径上有 / 字符
4.在#include "..."指令中使用的文件名不符合ISO:C90标准最严格的可移植性要求。为了达到这种严格的一致性,包含文件名必须限制在最多6个字母字符、一个句点(.)和一个字母字符。这些字符应该全部大写或全部小写。
5.未定义LWIP_SOCKET 宏,经过查找,发现在lwipopts.h文件里#define LWIP_SOCKET 0 /**< \brief default is 1 */,但是在chagen.c 文件里引用的opt.h包含lwipopts.h,QAC未识别出,是否需要手动添加LWIP_SOCKET = 0 ?
6.代码中使用int,违反了M3CM的"Avoid using basic numerical types directly"规则
7.#include "chargen.h"和"string.h"是多余的
8.图4的函数没有传入参数及返回值也没有外部连接,是多余的
ethernet.c
1.不允许多行注释
2.在#include "..."指令中使用的文件名不符合ISO:C90标准最严格的可移植性要求。为了达到这种严格的一致性,包含文件名必须限制在最多6个字母字符、一个句点(.)和一个字母字符。这些字符应该全部大写或全部小写。
gnss_boot.c
1.在#include "..."指令中使用的文件名不符合ISO:C90标准最严格的可移植性要求。为了达到这种严格的一致性,包含文件名必须限制在最多6个字母字符、一个句点(.)和一个字母字符。这些字符应该全部大写或全部小写。
gnss_boot_uart.c
1.在#include "..."指令中使用的文件名不符合ISO:C90标准最严格的可移植性要求。为了达到这种严格的一致性,包含文件名必须限制在最多6个字母字符、一个句点(.)和一个字母字符。这些字符应该全部大写或全部小写。
2.#include "stdio.h" 在#include "jupiter_debug.h"已经被包含.
3.#include "Uart.h"在#include "gnss_boot_uart.h"已经被包含
4.未命名的'struct'和'union'类型在迁移到C++时可能会导致可移植性问题。
5.大括号的使用不符合“exdented”风格
6.缩进 tab和空格混用导致进与文件中之前的缩进不一致错误
7.Use of basic type 'unsigned int'.避免使用基本类型“unsigned int”。
8.Use of basic type 'unsigned char'.避免使用基本类型“unsigned char”。
9.ISO:C90标准的最低要求(前6个字符内不唯一)内不唯一的情况,GNSS_Boot_UartStreamSize GNSS_Boot_UartTxInd等 不符合该条规定
10.匹配的大括号出现在同一行 - 建议使用正确的缩进。
11.文件范围静态变量“uart_rx_boot_buf_single”仅在一个函数中被访问,如果一个文件范围的静态变量仅在一个函数中被访问,那么它应该被声明为块范围的静态变量.
12.参数“size”和"status","count","ErrorId"从未被修改,因此可以用“const”限定符声明。
13.不允许使用显式或隐式的指针转换.
14.'memset' returns a value which is not being used.'memset'函数的返回值是无用的.
15.一个“unsigned short”类型的非恒定表达式正在被传递给更宽的无符号类型的函数参数,'unsigned int'。
16.Pointed to object has smaller size than the size_t argument存在数组越界的危险
17.有符号类型和无符号类型进行算术运算时会发生错误 if(Receivecnt < GNSS_Boot_GetUartStreamSize()-1)
18.timeoutCnt 是static uint16类型,但是却和int类型进行运算比较
19.图2的循环永远为真
20.图2 % 两边的类型不一样,会产生一个"signed int"
21.图2 == 两边的类型不一样,都将被提升为“signed int”以进行比较
22.图3 的flash_identifier 被定义为const 类型,过显式的类型转换去除了const限定符,因为这可能导致未定义行为,特别是如果试图通过非const指针修改原本应该是常量的数据。这违反了MISRA C标准中的规则11.4(强制),该规则要求在使用转换时必须确保转换不会去除任何类型限定符.
23.图4的!= 两边类型不一样,都将被提升为“signed int”以进行比较
24.图5的CombBaudData,baudrate_changed,host_ready,flash_ready被定义为const 类型,过显式的类型转换去除了const限定符,因为这可能导致未定义行为,特别是如果试图通过非const指针修改原本应该是常量的数据。这违反了MISRA C标准中的规则11.4(强制),该规则要求在使用转换时必须确保转换不会去除任何类型限定符.
25.图6的3个位运算的结果没有被显式地转换为它们的本质类型,可能存在未定义行为。
26.有非常多的 The operands of this relational operator are of different 'essential signedness' but will both be promoted to 'signed int' for comparison.问题
持续更新中