嵌入式c代码测评心得

函数式编程要归结于一句话:
高内聚,松耦合,高扇入,合理扇出

高内聚:
内聚是函数内各个元素彼此结合的紧密程度。越紧密代表了函数的独立性越强。
松耦合:
耦合是一个软件结构内不同函数之间互连程度的度量,耦合性也叫块间联系。模块之间尽量有紧密联系
高扇入:
扇入是一个函数被其他函数调用的次数。被调用越多代表这个函数价值越高
合理扇出(<7):
扇出是一个函数内部调用其他函数的次数,调用函数越多,当其中一个函数变化时会影响被调用函数。
嵌入式c也是有单元测试的,例如 CUnit,主要是断言和log显示结果~~以后再分析

公司采用的都是华为规范来进行代码测评

1,逻辑连接符需加括号

extern BOOL get_bool ( void );
void static_49(void)
{
   BOOL flag = TRUE;
   INT_32 y = 0, x = 0, z = 1;
   if (x < 0 || z + y != 0)  /* not compliant - 逻辑运算符两边运算要加括号 */
   {
      flag = FALSE;
   } 
   if ( flag && get_bool() )  /* not compliant - 设置206可不报错,否则报错 */
   {
      flag = FALSE;
   }    
}

2,存在空语句

if(1)
{
		/*如果空语句是故意的,添加一个/**/*/
}

3.对有符号类型位操作
对有符号数进行位操作时非常不安全的行为。例如,与(&)或者或(|)操作符对于结果的执行时非常明确地,这就有可能导致标志位丢失,或者把数值换到了符号位当中。

void static_120(void)
{
   SINT_32 b = 1;
 
   b = b | 1; /* not compliant */
 }

4,复杂表达式中使用VOLATILE变量
volatile变量的值可能在使用过程中而被改变(非控制改变)。这个标准可以把在表达式中使用相同volatile变量多于一次的表达式报告出来。因为返回的值有可能是各个阶段表达式的值,所以有可能是不一样的,这种情况是不安全的。安全的做法是在简单不可再优化表达式中只使用变量一次。如果需要在所有表达式的部分中使用同样的值,最好是把当前值保留在一个局部变量中,用局部变量来代表volatile变量,再用于表达式当中。

volatile UINT_32 v = 1U;
UINT_32 x, a;
x = v*v; /* this is unsafe, v could change*/ 
a = v;
x = a*a; /* this is safe, the value of v was captured */ 

5,有符号/无符号间无强制类型转换
不同类型之间的转换需要使用显式强制类型转换,以说明类型转换是人为的,不存在无意中丢失的信息(或已知晓会丢失)。默认类型转换是比较有代表性的定义操作,这种操作有可能导致未定义的行为发生。

void static_434(UINT_32 us1)
{
  SINT_32 ss1 = us1;  /* converting to signed may result in a loss of information */ 
  /* ... */ 
}

6,默认转换为范围更窄整型
转换成一个更小范围的类型需要使用强制类型转换,以说明类型转换是人为的,不存在无意中丢失的信息(或已知晓会丢失)。默认类型转换是比较有代表性的定义操作,这种操作有可能导致未定义的行为发生。

static void static_446 ( void )
{
  UINT_16 u16;
  UINT_32 u32a,
          u32b;
 
  u16 = u32a + u32b;  /* not compliant – 会默认从32位转换成16位 */ 
}

7,if,else需要加括号
8,枚举初始化

enum (x,y,z)	       /*GOOD (unless type 377 is set) – 未明确初始化*/ 
enum (x=1,y,z)      /*GOOD – 只初始化第一个值*/ 
enum (x=2,y=3,z=4)  /*GOOD – 初始化所有值*/ 
enum (x,y,z=1)      /*BAD – 不允许只初始化部分*/ 

不规范案例

enum
{
		a = 0x01,
		b,
		c=0xff,
}

9,必须要有形参

{
	void fun(void)
}

10,函数返回局部结构体
一个函数不应该返回一个指向局部结构体对象的指针。在被调用函数的返回后,局部对象会存在于数据范围之外并且不再存在。

struct tag
{
   UCHAR  * uptr;
};
 
static struct tag SDA_077 (void)
{
   UCHAR  loc = 42;
 
   struct tag rtag;
   rtag.uptr = &loc;
 
   return   rtag; /* Not compliant  */ 
}

11,指针相减地址并不指向数组
指向不同对象的指针不能直接相减,这样得出的地址指向的并不是数组,且有可能会导致无法定义的行为发生。

typedef signed int Sint_32;
  
void foo(void)
{
  Sint_32 ss1[10];
  Sint_32 ss2[10];
 
  Sint_32 *ss1_ptr = &ss1[0];
  Sint_32 *ss2_ptr = &ss2[0];
  Sint_32 ss3 = ss1_ptr - ss2_ptr; 
/* not compliant – 指向不同数组的指针不能直接相减*/
 
}

12,IF语句中没有ELSE分支
13,数组初始化 应该赋值为0,尽管bbs段默认赋值为0
14,FOR循环语句初始化过于复杂
For循环中的初始化表达式(即第一项)不应该存在执行语句,除了给循环参数赋一个简单值。

void static_270(void)
{
  UINT_32 loop;
  UINT_32 myVar = 0U;
  const UINT_32 max = 10U;
 
  for ( ++myVar, loop = 0U; loop < max; loop++ ) /* not compliant */
  {
    /* ... */
  }
}

15,结构成员名称重用

struct I_var_a
{
  INT_32 ip1;
  INT_32 ip2;
} I_var_a;
 
struct I_var_b
{
  INT_32 ip2;   /* not compliant */ 
  INT_32 ip3;
  INT_32 ip4;
} I_var_b;

16,强制转换VOLATILE 值
尽量避免抛弃volatile条件,因为这有可能会导致编译器最优化有效执行时,在建立优化的时候出现意想不到的结果。

volatile UINT_32 *y1;
 
static void static_344 ( void )
{
   UINT_32 *y2 = (UINT_32 *)y1;  
/* not compliant - cast to ... a pointer to non-volatile int */ 
}  

17,循环中不止一条break/goto
所有内部操作中都应该最多只有一条break语句来用于结束一个循环。如果代码是良好结构的,那是没有必要使用多于一个break语句的。

#include "c_standards.h"
#include <stdio.h>
 
const INT_32 max_num = 10;
 
void static_409( char arr[] )
{
  INT_32 sub;
 
  for (sub = 0; sub < max_num; sub++)
  {
    if (arr[sub] == '\0')
    {
      break;
    }
 
    (void) printf("%c", arr[sub]);
 
    if (arr[sub] == 'z')
    {
      break;  /* not compliant – 这个循环已经出现过一次break了*/
    }
  } 
}

18, 指针运算不在数组上
在非数组的指针上进行算术运算被认为是非常不安全的做法(直接对地址进行操作),因为这样很难保证结果是在有效地址上的。

#include "c_standards.h" 
 
static void static_567( UINT_32 * pp );
 
static void static_567( UINT_32 * pp )
{
  UINT_32 * xx;
  xx = pp +7;    /* not compliant */ 
}

19,在循环体内改变循环计数
一个循环计数是在循环中用于反复计数的,不应该在循环体内被改变。改变循环计数变量会导致代码难以阅读和维护。

static void SDA_055( UINT_32 max_count )
{
  UINT_32 loop_counter = 0U;
 
  for (loop_counter = 0U; loop_counter < max_count; loop_counter++)
  {
    if (loop_counter == 7U)
    {
      loop_counter++;   /* not compliant */
    }
    else
    {
      /* do nothing  */
    }
  }
}

猜你喜欢

转载自blog.csdn.net/qq_32166779/article/details/86691006