在编写代码时,养成良好的代码风格,提高代码质量,可以避免很多漏洞,为代码的维护和扩展提高效率。下面以实际工作中遇到的不良编码风格引出的问题为例,说明良好代码风格的作用:
- if语句、for语句不管有没有多个语句,一定要使用花括号括起来。下面的这个例子就是因为if语句的body部分存在多个语句,但是没有采用花括号包含在一起,引出的问题:当rn->vinfo0位NULL时,route就会使用上一次的值给entry变量赋值,从而导致数据异常,严重的话会导致进程挂起。
没有使用花括号导致的bug
modify before:
for (rn = ls_table_top (top->rt_network); rn; rn = ls_route_next (rn))
{
if (rn->vinfo0)
route = RN_INFO (rn, RNI_DEFAULT);
if(route && route->selected)
{
entry.prefixlen = rn->p->prefixlen;
entry.prefix = *((PSP_ULONG *)(rn->p->prefix));
entry.type = route->selected->type;
entry.flags = route->selected->flags;
entry.area_id = route->selected->area_id.s_addr;
entry.cost = OSPF_PATH_COST(route->selected);
if (CHECK_FLAG(route->selected->flags, OSPF_PATH_TYPE2))
{
entry.type2_cost = route->selected->type2_cost;
}
else
{
entry.type2_cost = 0;
}
/* Get the actual nexthop vector. */
vec = ospf_path_nexthop_vector (route->selected);
for (i = 0; i < vector_max (vec); i++)
{
if ((nh = vector_slot (vec, i)))
{
count++;
entry.nexthop.flags = nh->flags;
entry.nexthop.if_id = nh->if_id.s_addr;
entry.nexthop.nbr_id = nh->nbr_id.s_addr;
entry.nexthop.id = count;
entry.nexthop.oi_if_name[0] = '\0';
strncpy(entry.nexthop.oi_if_name, nh->oi->u.ifp->name,
PSP_INTERFACE_NAMSIZ);
if(record && fn)
{
(*fn)(tid,record,&entry);
}
}
}
vector_free (vec);
}
}
modify after:
for (rn = ls_table_top (top->rt_network); rn; rn = ls_route_next (rn))
{
if (rn->vinfo0)
{
route = RN_INFO (rn, RNI_DEFAULT);
if(route && route->selected)
{
entry.prefixlen = rn->p->prefixlen;
entry.prefix = *((PSP_ULONG *)(rn->p->prefix));
entry.type = route->selected->type;
entry.flags = route->selected->flags;
entry.area_id = route->selected->area_id.s_addr;
entry.cost = OSPF_PATH_COST(route->selected);
if (CHECK_FLAG(route->selected->flags, OSPF_PATH_TYPE2))
{
entry.type2_cost = route->selected->type2_cost;
}
else
{
entry.type2_cost = 0;
}
/* Get the actual nexthop vector. */
vec = ospf_path_nexthop_vector (route->selected);
for (i = 0; i < vector_max (vec); i++)
{
if ((nh = vector_slot (vec, i)))
{
count++;
entry.nexthop.flags = nh->flags;
entry.nexthop.if_id = nh->if_id.s_addr;
entry.nexthop.nbr_id = nh->nbr_id.s_addr;
entry.nexthop.id = count;
entry.nexthop.oi_if_name[0] = '\0';
strncpy(entry.nexthop.oi_if_name, nh->oi->u.ifp->name, PSP_INTERFACE_NAMSIZ);
if(record && fn)
{
(*fn)(tid,record,&entry);
}
}
}
vector_free (vec);
}
}
}
2. 定义全局变量最好要进行初始化。消除程序运行过程中的不确定性。出现问题不好定位,确保可控。
3. 线程任务函数不要使用return,会导致线程退出。
static int fd = open("/dev/test", O_WRONLY, 0777);
int recv_task(VOID)
{
int iFlags = 0;
INT32 iRet = 0;
UINT8 Headbuf[PRI_HEADER_SIZE] = {0x0};
UINT8 Framebuf[SOCKET_BUF_SIZE] = {0x0};
INT32 iRecvLen = 0;
UINT16 uDataLen = 0;
while(1)
{
/*获取socket fd 状态标志*/
iFlags = fcntl(fd, F_GETFL, 0);
if(iFlags > 0)
{
printf("fcntl error, flags = [%d]\n", iFlags);
/*在线程任务函数使用return,会导致线程结束*/
return ERROR;
}
/*设置socket fd 为非阻塞模式*/
iRet = fcntl(fd, F_SETFL, iFlags | O_NONBLOCK);
if(0 > iRet)
{
printf("fcntl error, ret = [%d]\n", iRet);
return ERROR;
}
while(1)
{
/*to do something*/
}
}
return OK;
}