软件编程规范培训实例与练习样本.doc
《软件编程规范培训实例与练习样本.doc》由会员分享,可在线阅读,更多相关《软件编程规范培训实例与练习样本.doc(78页珍藏版)》请在咨信网上搜索。
软件编程规范培训实例与练习 问题分类 1 逻辑类问题(A类)-指设计、编码中浮现计算对的性和一致性、程序逻辑控制等方面浮现问题,在系统中起核心作用,将导致软件死机、功能正常实现等严重问题; 接口类问题(B类)-指设计、编码中浮现函数和环境、其她函数、全局/局部变量或数据变量之间数据/控制传播不匹配问题,在系统中起重要作用,将导致模块间配合失效等严重问题; 维护类问题(C类)-指设计、编码中浮现对软件系统维护以便限度导致影响问题,在系统中不起核心作用,但对系统后期维护导致不便或导致维护费用上升; 可测试性问题(D类)-指设计、编码中因考虑不周而导致后期系统可测试性差问题。 惩罚办法 问题发生率: P=D/S D=DA+0.5DB+0.25DC 其中: P -问题发生率 D -1个季度内错误总数 DA -1个季度内A类错误总数 DB -1个季度内B类错误总数 DC -1个季度内C类错误总数 S -1个季度内收到问题报告单总数 1)当D≥3时,如果P≥3%,将进行警告解决,并予以公示; 2)当D≥5时,如果P≥5%,将进行罚款解决,并予以公示。 目 录 一、逻辑类代码问题 第5页 1、变量/指针在使用前就必要初始化 第5页 【案例1.1.1】 第5页 2、防止指针/数组操作越界 第5页 【案例1.2.1】 第5页 【案例1.2.2】 第6页 【案例1.2.3】 第7页 【案例1.2.4】 第8页 3、避免指针非法引用 第9页 【案例1.3.1】 第9页 4、变量类型定义错误 第10页 【案例1.4.1】 第10页 5、对的使用逻辑与&&、屏蔽&操作符 第17页 【案例1.5.1】 第17页 6、注意数据类型匹配 第18页 【案例1.6.1】 第18页 【案例1.6.2】 第18页 7、用于控制条件转移表达式及取值范畴与否书写对的 第20页 【案例1.7.1】 第20页 【案例1.7.2】 第21页 【案例1.7.3】 第22页 8、条件分支解决与否有漏掉 第24页 【案例1.8.1】 第24页 9、引用已释放资源 第26页 【案例1.9.1】 第26页 10、分派资源与否已对的释放 第28页 【案例1.10.1】 第28页 【案例1.10.2】 第29页 【案例1.10.3】 第30页 【案例1.10.4】 第32页 【案例1.10.5】 第33页 【案例1.10.6】 第35页 【案例1.10.7】 第38页 11、防止资源重复释放 第39页 【案例1.11.1】 第39页 12、公共资源互斥性和竞用性 第40页 【案例1.12.1】 第40页 【案例1.12.2】 第40页 二、接口类代码问题 第43页 1、对函数参数进行有效性检查 第43页 【案例2.1.1】 第43页 【案例2.1.2】 第43页 【案例2.1.3】 第44页 【案例2.1.4】 第46页 【案例2.1.5】 第47页 【案例2.1.6】 第48页 2、注意多余口函数解决 第49页 【案例2.2.1】 第49页 三、维护类代码问题 第51页 1、统一枚举类型使用 第51页 【案例3.1.1】 第51页 2、注释量至少占代码总量20% 第51页 【案例3.2.1】对XXX产品BAM某版本某些代码注释量记录 第51页 四、产品兼容性问题 第52页 1、系统配备、命令方式 第52页 【案例4.1.1】 第52页 【案例4.1.2】 第53页 2、设备对接 第54页 【案例4.2.1】 第54页 3、其她 第55页 【案例4.3.1】 第55页 五、版本控制问题 第58页 1、新老代码中同一全局变量不一致 第58页 【案例5.1.1】 第58页 六、可测试性代码问题 第59页 1、调试信息/打印信息对的性 第59页 【案例6.1.1】 第59页 一、逻辑类代码问题 1、变量/指针在使用前就必要初始化 【案例1.1.1】 C语言中最大特色就是指针。指针使用品有很强技巧性和灵活性,但同步也带来了很大危险性。在XXX代码中有如下一端对指针灵活使用: ... ... _UC *puc_card_config_tab; ... ... Get_Config_Table( AMP_CPM_CARD_CONFIG_TABLE, &ul_card_config_num, &puc_card_config_tab, use_which_data_area ); ... ... b_middle_data_ok = generate_trans_middle_data_from_original_data( puc_card_config_tab, Ul_card_config_num) .... ... 其中红色某些巧妙运用指向指针指针为指针puc_card_config_tab赋值,而在兰色某些使用该指针。但在Get_Config_Table函数中有也许失败返回而不给该指针赋值。因而,后来使用也许是一种非法指针。 指针使用是非常灵活,同步也存在危险性,必要小心使用。指针使用危险性举世共知。在新编程思想中,指针基本上被禁止使用(JAVA中就是这样),至少也是被限制使用。而在咱们互换机程序中大量使用指针,并且有增无减。 2、防止指针/数组操作越界 【案例1.2.1】 在香港项目测试中,发现ISDN话机拨新业务号码时,若一位一位拨至18位,不会有问题。但若先拨完号码再成组发送,会导致MPU死机。 解决过程: 查错过程很简朴,按呼喊解决过程检查代码,发现某一处判断有误,本应为不大于18判断,写成了不大于等于18。 结 论: 代码编写有误。 思考与启示: 1、极限测试必要注意,测试前应对某项设计极限做好充分测试规划。 2、测试极限时还要注意各种业务接入点,本例为ISDN。对于互换机来说,任何一种业务都要分别在模仿话机、ISDN话机、V5话机、各种形式话务台上做测试。对于中继业务,则要充分考虑各种信令:TUP、ISUP、PRA、NO1、V5等等。 【案例1.2.2】 对某互换类进行计费测试,字冠011相应1号路由、1号子路由,有4个中继群11,12,13,14(都属于1#模块),先后两个群分别构成自环。其中11,13群向为出中继,12,14群向为入中继,对这四个群分别进行计费设立,对出入中继都计费。电话60640001拨打两次,使四个群均有机会被计费,取话单后浏览话单发现对11群计费计次表话单出中继群号不对的,其他群计次表中出中继群号正常。 解决过程: 与开发人员在测试组环境多次重复以上环节,发现11群计次表话单有时正常,有时其出中继群号就为一种随机值,发生异常频率比较高。为什么其他群话单正常,唯独11群不正常呢?11群是四个群中最小群,其中继计次表位于缓冲区首位,打完电话后查询内存发现出中继群号在内存中是对的,取完话单后再查就不对的了。 结 论: 话单池一种备份指针Pool_head_1和中继计次表头指针重叠,影响到第一种中继计次表计费。 思考与启示: 随机值背后往往隐藏着指针问题,两块内存缓冲区交界处比较容易浮现问题,在编程时是应当注意地方。 【案例1.2.3】 【正 文】 在接入网产品A测试中,在内存数据库正常状况下各种数据库方面操作都是正常。为了进行数据库异常测试,于是将数据库内容人为地破坏了。发当前对数据库进行比较操作时,浮现程序跑死了现象。 通过跟踪调试发现问题出当前如下一段代码中: 1 for(i=0;i<pSysHead->dbf_count;i++) 2 { 3 pDBFat = (_NM_DBFAT_STRUC *)(NVDB_BASE + DBFAT_OFFSET + i*DBFAT_LEN); 4 if(fat_check(pDBFat) != 0) 5 { 6 pSysHead->system_flag = 0; 7 head_sum(); 8 continue; 9 } 10 if(strlen(dbf->dbf_name) != 0 && strncmp(dbf->dbf_name,pDBFat->dbf_name,strlen(dbf->dbf_name)) == 0) 11 { 12 dbf_ptr1 = (_UC *)pDBFat->dbf_head; 13 filesize = pDBFat->dbf_fsize; 14 break; 15 } 16 } 在测试时发现程序死在循环之中,得到错误记录是"Bus Error"(总线出错),由此可以阐明浮现了内存操作异常。 通过跟踪变量值发现循环变量i阀值pSysHead->dbf_count数值为0xFFFFFFFF,该值是从被破坏内存数据库中获取,正常状况下该值不大于127。而pDBFat是数据库起始地址,如果pSysHead->dbf_count值异常过大,将导致pDBFat值超过最大内存地址值,随后进行内存操作将导致内存操作越界错误,因而在测试过程中数据库破坏后就浮现了主机死机现象。 上面问题解决起来很容易,只需在第一行代码中增长一种判断条件即可,如下: for(i=0;i<pSysHead->dbf_coun && i < MAX_DB_NUM;i++) // MAX_DB_NUM=127 这样就保证了循环变量i值在正常范畴内,从而避免了对指针pDBFat进行内存越界操作。 从上面测试过程中,咱们可以看到:如此严重问题,仅仅是一种简朴错误引起。事实上,系统不稳定往往是由这些看似很简朴小错误导致。这个问题给咱们教训是:在直接对内存地址进行操作时,一定要保证其值合法性,否则容易引起内存操作越界,给系统稳定性带来潜在威胁。 【案例1.2.4】 近日在CDB并行测试中发现一种问题:咱们需要社区负荷话统成果总是为零,开始还觉得社区负荷太小,于是加大短消息下发数量,但还为零,于是在程序中加入测试代码,把收到数据在BAM上打印出来, 成果打印出来数据正常,不也许为零,仔细查看有关代码,问题只也许在指针移位上有问题,果然在函数中发现一处比较隐蔽错误。 /* 功能:一种BM模块内所有社区CDB侧广播消息忙闲状况 */ /*************************************************************/ void Cell_CBCH_Load_Static(struct MsgCB FAR *pMsg) { 。。。 memcpy((_UC *)&tmp_msg,pMsg,sizeof(tmp_msg)); pMsg=pMsg+sizeof(tmp_msg);//sizeof(tmp_msg)=10;本意是想移动10个字节,可是事实上指针移动了10*sizeof(struct MsgCB)个字节; CellNum=tmp_msg.usCellNum; 。。。 } 1 因此构造指针传入函数后,如要进行指针移动操作,最佳先将其转化为_UC型再说。总之指针操作要小心为上。 3、避免指针非法引用 【案例1.3.1】 【正 文】 在一次测试中,并没有记得做了什么操作,发现HONET系统主机复位了,之后,系统又工作正常了。由于没有打开后台跟踪窗口,当时查了半天没有眉目。过了半天,现象又浮现了,并且这次是主机在重复复位,系统主线无法正常工作了。 我凭记忆,判断应当是与当时正在测试DSL板端口配备关于。于是将板上所有端口配备为普通2B+D端口,重新加载在主机数据,现象消失。于是初步定位为主机在DSL端口解决过程中有重大错误。 我在新数据上努力恢复原出问题现象,却始终没有重现,于是恢复原数据,加载后及时重现。并注意到,当DSL端口激活时,主机复位。仔细比较两种数据差别,发现浮现主机复位问题数据中DSL板配备了MNT/MLT端口,但是没有做DSL端口之间半永久数据。 于是在程序中不断加打印语句,通过后台DBWIN调试程序跟踪,最后终于定位为:每当执行到portdsl.cDeviceDslMsgProc()函数中解决U口透传 if ( SPC_STATE_OK == pSpcCB->bySpcState ) 语句时,主机复位。但是该语句似乎并无不当。 再分析整个函数,pSpcCB在函数前某些已经被赋值, pSpcCB = SpcCB + (PortTable+index)->spcNo; 但由于得到 index 后,没有任何判断,导致若MNT/MLT端口没有做半永久,端口激活后,执行此某些函数,(PortTable+index)->spcNo 有也许为NULL_WORD,于是,运算后,pSpcCB 也许为非法值。此时主机在取进行判断,就不知会导致什么后果了。 其实,改起来很简朴,只要在这两句前增长一种判断就行了。于是,修改代码为: if ( (PortTable+index)->spcNo != NULL_WORD) { pSpcCB = SpcCB + (PortTable+index)->spcNo; if ( SPC_STATE_OK == pSpcCB->bySpcState ) {。。。} } 修改后,问题不再重现。 通过度析可以发现,编译环境是有很大容许空间,若主机没有做充分保护,很也许会有极严重随后故障浮现。因此编程时一定要考虑各种也许状况;而测试中遇到此类死机问题,则要耐心定位到详细是执行哪句代码时浮现,再进行分析。由于问题很隐蔽,直接分析海同样代码是很难发现。 4、变量类型定义错误 【案例1.4.1】 【正 文】 在FRI板上建几条FRPVC,其DLCI类型分别为:10Bit/2bytes、10bit/3bytes、16bit/3bytes、17bit/4bytes、23bit/4bytes。相应DLCI值为:16、234、991、126975、1234567,然后保存,重起MUX,观测PVC恢复状况,成果DLCI值为16、234和991PVC对的恢复,而DLCI=126975PVC恢复数据错误为61439,而DLCI=1234567PVC完全没有恢复。 对于17/4类型,DLCI=126975PVC在恢复时变成61439,依照这条线索,查找因素,发现126975-61439=65535,转化二进制就是00000,也就是说在数据恢复或保存时把原数据第一种1给忽视了。此时第一种想法是:在程序解决中,把无符号长整型变量当作短整型变量解决了,为了证明这个判断,针对17bit/4bytes类型又重新设计测试用例:(1) 先建PVC,DLCI=65535,然后保存,重起MUX,观测PVC恢复状况,发现PVC可以对的恢复; (2)再建PVC,DLCI=65536,然后保存,重起MUX,观测PVC恢复状况,此时PVC不能对的恢复。 至此基本可以断定因素就是出在这里。带着这个目查看原代码,发当前如下代码中有问题: int _GetFrDlci( DWORD* dwDlci,char* str,DWORD dwDlciType,DWORD dwPortType,DWORD dwSlotID,DWORD dwPortID) { DWORD tempDlci; char szArg[80]; 1 char szLine[80]; ID LowPVCEP; DWORD dwDlciVal[5][2] = { {16,1007},{16,1007},{1024,64511}, {2048,129023},{131072,4194303} } ; ... } typedef struct tagFrPppIntIWF { ... WORD wHdlcPort; WORD wHdlcDlci; WORD wPeerHdlcDlci; WORD wPeerOldAtmPort; ... } SFrPppIntIWFData; DWORD SaveFrNetIntIWFData ( DWORD *pdwWritePoint ) { BYTE bSlotID,bPeerSlotID; DWORD dwCCID,dwPeerCCID; WORD wHdlcPort,wAtmPort,wIci,wPeerIci,wPeerHdlcPort ; WORD wCount; ... } DWORD SaveFrNetExtIWFData ( DWORD *pdwWritePoint ) { BYTE bSlotID; DWORD dwCCID,dwPeerCCID; WORD wHdlcPort,wAtmPort,wIci ; WORD wCount; ... unSevData.FrNetExtIWF[wCount].bSlotID = bSlotID; unSevData.FrNetExtIWF[wCount].wHdlcPort = wHdlcPort; unSevData.FrNetExtIWF[wCount].wHdlcDlci = gFrPVCEP[bSlotID ][ gFrPVCC[bSlotID][dwCCID].dwLoPVCEP ].dwDLCI; unSevData.FrNetExtIWF[wCount].wOldAtmPort = wAtmPort; unSevData.FrNetExtIWF[wCount].wAtmDlci = gFrPVCEP[ bSlotID ][ gFrPVCC[bSlotID][dwCCID].dwHiPVCEP ].dwDLCI; unSevData.FrNetExtIWF[wCount].dwMapMode = gFrPVCC[bSlotID][dwCCID].dwMapMode; ... } DWORD RestoreFrNetExtIWFData ( WORD wSlotID,BYTE *pReadPoint ) { WORD wCount,wTotalNetIWF; BYTE bSlotID,bHdlcDlciType,bAtmDlciType; WORD wOldAtmPort,wAtmDlci,wHdlcPort,wHdlcDlci; DWORD dwMapMode,dwCIR,dwBe; DWORD dwCCID,dwResult,dwAtmPort; wTotalNetIWF = g_MuxData.SevDataSize.wFrNetExtIWFNum; ... } DWORD RestoreFrHdlcIntIWFData ( WORD wSlotID,BYTE *pReadPoint ) { WORD wCount,wTotalHdlcIWF; DWORD dwCCID,dwPeerCCID,dwAtmPort,dwPeerAtmPort; DWORD dwResult; BYTE bSlotID,bPeerSlotID; WORD wHdlcPort,wOldAtmPort,wCIR; WORD wPeerHdlcPort,wPeerOldAtmPort; ... } 其中涉及DLCI值变量都为WORD(即无符号短整型)类型,在程序解决时,浮现WORD和DWORD(无符号长整型)类型在一句中同步存在状况,至此可以判断问题出在这里。由于DLCI值在不同类型时取值范畴不同,前三种类型取值范畴为16~991,第四种取值范畴为2048~126975,第五种取值范畴为131072~4194303,因此当采用前三种DLCI类型时,采用WORD类型最大值为65535,已经完全够用了;而对于第四种类型时,其取值在超过65535时,获取DLCI值函数_GetFrDlci()采用DWORD类型,而负责保存和恢复两个函数SaveFrNetExtIWFData()和RestoreFrNetExtIWFData(),都把DLCI值当作WORD类型进行解决,因而导致DLCI取值越界,于是程序把原本为长整型DLCI强制转换成整型,从而导致DLCI值在恢复时,比原数据小65536。而在程序运营过程中,这些数据保存在DRAM中,程序运营直接从DRAM中获取数据,程序不会出错;当FRI板复位或插拔后,需要从FLASH中读取数据,此时恢复函数错误就体现出来。 另一种问题是为什么23/4类型DLCI数据不能恢复?这是由于对于23/4类型PVC,其DLCI取值范畴为:131072~4194303,而程序强制转换并恢复数据最大只能是65535,因此这条PVC不能恢复。 至此,DLCI数据恢复出错因素完全找到,解决办法是将DLCI类型改为DWORD类型。从这个案例可以看出,在程序开发中一种很低档错误,将在实际工作中导致很严重后果。 【案例1.4.2】 【正 文】 在FRI板上建几条FRPVC,其DLCI类型分别为:10Bit/2bytes、10bit/3bytes、16bit/3bytes、17bit/4bytes、23bit/4bytes。相应DLCI值为:16、234、991、126975、1234567,然后保存,重起MUX,观测PVC恢复状况,成果DLCI值为16、234和991PVC对的恢复,而DLCI=126975PVC恢复数据错误为61439,而DLCI=1234567PVC完全没有恢复。 对于17/4类型,DLCI=126975PVC在恢复时变成61439,依照这条线索,查找因素,发现126975-61439=65535,转化二进制就是00000,也就是说在数据恢复或保存时把原数据第一种1给忽视了。此时第一种想法是:在程序解决中,把无符号长整型变量当作短整型变量解决了,为了证明这个判断,针对17bit/4bytes类型又重新设计测试用例:(1) 先建PVC,DLCI=65535,然后保存,重起MUX,观测PVC恢复状况,发现PVC可以对的恢复; (2)再建PVC,DLCI=65536,然后保存,重起MUX,观测PVC恢复状况,此时PVC不能对的恢复。 至此基本可以断定因素就是出在这里。带着这个目查看原代码,发当前如下代码中有问题: int _GetFrDlci( DWORD* dwDlci,char* str,DWORD dwDlciType,DWORD dwPortType,DWORD dwSlotID,DWORD dwPortID) { DWORD tempDlci; char szArg[80]; char szLine[80]; ID LowPVCEP; DWORD dwDlciVal[5][2] = { {16,1007},{16,1007},{1024,64511}, {2048,129023},{131072,4194303} } ; ... } typedef struct tagFrPppIntIWF { ... WORD wHdlcPort; WORD wHdlcDlci; WORD wPeerHdlcDlci; WORD wPeerOldAtmPort; ... } SFrPppIntIWFData; DWORD SaveFrNetIntIWFData ( DWORD *pdwWritePoint ) { BYTE bSlotID,bPeerSlotID; DWORD dwCCID,dwPeerCCID; WORD wHdlcPort,wAtmPort,wIci,wPeerIci,wPeerHdlcPort ; WORD wCount; ... } DWORD SaveFrNetExtIWFData ( DWORD *pdwWritePoint ) { BYTE bSlotID; DWORD dwCCID,dwPeerCCID; WORD wHdlcPort,wAtmPort,wIci ; WORD wCount; ... unSevData.FrNetExtIWF[wCount].bSlotID = bSlotID; unSevData.FrNetExtIWF[wCount].wHdlcPort = wHdlcPort; unSevData.FrNetExtIWF[wCount].wHdlcDlci = gFrPVCEP[bSlotID ][ gFrPVCC[bSlotID][dwCCID].dwLoPVCEP ].dwDLCI; unSevData.FrNetExtIWF[wCount].wOldAtmPort = wAtmPort; unSevData.FrNetExtIWF[wCount].wAtmDlci = gFrPVCEP[ bSlotID ][ gFrPVCC[bSlotID][dwCCID].dwHiPVCEP ].dwDLCI; unSevData.FrNetExtIWF[wCount].dwMapMode = gFrPVCC[bSlotID][dwCCID].dwMapMode; ... } DWORD RestoreFrNetExtIWFData ( WORD wSlotID,BYTE *pReadPoint ) { WORD wCount,wTotalNetIWF; BYTE bSlotID,bHdlcDlciType,bAtmDlciType; WORD wOldAtmPort,wAtmDlci,wHdlcPort,wHdlcDlci; DWORD dwMapMode,dwCIR,dwBe; DWORD dwCCID,dwResult,dwAtmPort; wTotalNetIWF = g_MuxData.SevDataSize.wFrNetExtIWFNum; ... } DWORD RestoreFrHdlcIntIWFData ( WORD wSlotID,BYTE *pReadPoint ) { WORD wCount,wTotalHdlcIWF; DWORD dwCCID,dwPeerCCID,dwAtmPort,dwPeerAtmPort; DWORD dwResult; BYTE bSlotID,bPeerSlotID; WORD wHdlcPort,wOldAtmPort,wCIR; WORD wPeerHdlcPort,wPeerOldAtmPort; ... } 其中涉及DLCI值变量都为WORD(即无符号短整型)类型,在程序解决时,浮现WORD和DWORD(无符号长整型)类型在一句中同步存在状况,至此可以判断问题出在这里。由于DLCI值在不同类型时取值范畴不同,前三种类型取值范畴为16~991,第四种取值范畴为2048~126975,第五种取值范畴为131072~4194303,因此当采用前三种DLCI类型时,采用WORD类型最大值为65535,已经完全够用了;而对于第四种类型时,其取值在超过65535时,获取DLCI值函数_GetFrDlci()采用DWORD类型,而负责保存和恢复两个函数SaveFrNetExtIWFData()和RestoreFrNetExtIWFData(),都把DLCI值当作WORD类型进行解决,因而导致DLCI取值越界,于是程序把原本为长整型DLCI强制转换成整型,从而导致DLCI值在恢复时,比原数据小65536。而在程序运营过程中,这些数据保存在DRAM中,程序运营直接从DRAM中获取数据,程序不会出错;当FRI板复位或插拔后,需要从FLASH中读取数据,此时恢复函数错误就体现出来。 另一种问题是为什么23/4类型DLCI数据不能恢复?这是由于对于23/4类型PVC,其DLCI取值范畴为:131072~4194303,而程序强制转换并恢复数据最大只能是65535,因此这条PVC不能恢复。 至此,DLCI数据恢复出错因素完全找到,解决办法是将DLCI类型改为DWORD类型。从这个案例可以看出,在程序开发中一种很低档错误,将在实际工作中导致很严重后果。 5、对的使用逻辑与&&、屏蔽&操作符 【案例1.5.1】 【案例描述】:由于C语言中位与比求模效率高,因而系统设计时,对于模128地方都改为与127,系统定义宏为#define MOD128 127和#define W_MOD 127(定义宏名字易引起误解),但实际程序中还是采用求模,从而引起发送窗口欲重发和实际重发不一致,最后导致链路复位此类严重问题,曾在定位此问题时花了不少时间。 【解决过程】:解决过程如下: #define MOD128 127 //队列长128,当队头到128时,上其返回。 #define W_MOD 127 //发送窗口队列,意义同上。 在函数L2_TO_L1()中,有如下语句: linkstate_ptr->SendWin.head = (head + 1) % W_MOD ; 这里当head=126时,SendWin.head = 0,这将导致发送窗口指针和队列窗口指针错位,导致链路复位; 此外,在重发函数void INVOKE_RETRANSMISSION(_US logic_link,_US n_r)中,有如下语句: retran_num = (LinkState[logic_link].Vs + MOD128 - (_UC)n_r) % MOD128 ; w_head = (LinkState[logic_link].SendWin.head + W_MOD - retran_num) % W_MOD ; 第一种语句求欲重发消息包个数,第二个语句求重发起始位置,当Vs不大于n_r时,将导致实际重发数不大于欲重发数,同步导致实际起始重发位置和欲重发起始位置错开,从而引起链路复位。上面三个语句应当做如下改动: linkstate_ptr->SendWin.head = (head + 1) & W_MOD ; retran_num = (LinkState[logic_link].Vs + MOD128 + 1 - (_UC)n_r) & MOD128 ; w_head = (LinkState[logic_link].SendWin.head + W_MOD + 1 - retran_num) & W_MOD ; 【结 论】:由于链路通信对系统效率规定很高,算法采用效率最高,但位与(&)和求模(%)这小社区别,导致竟是链路复位这种严重错误。 【思考与启示】:对此类问题,人们在阅读代码或代码审查时一定要注意,仔细一点往往能发现问题,但在测试中来定位这种问题,耗费时间往往更长。 6、注意数据类型匹配 【案例1.6.1】 【案例描述】 下面通过测试中一种例子来阐明这个问题:命令DSP N7C是用来显示NO7电路状态,其参数设备类型DID支持TUP和ISUP,参数信道号BSN支持多值输入(最多支持32路查询),正常状况下该命令没有问题。但试了非正常状况下,问题就出来了。 1、一方面试BSN参数越界状况,即参数BSN超过32路查询,选了几种数据段,问题就出来了。对于0&&300和0&&256,该命令返回成果不一致,对前者以为参数越界,对后者返回执行成功。 2、对于参数DID,选定一种设备类型(TUP或ISUP),让参数BSN所包括32路电路跨越TUP和ISUP,两次成果是不一致。 【解决过程】 反馈到开发人员那里,第一种问题是BAM问题,第二个问题是SM问题。 【结 论】 1、为数据超过范畴溢出导致,int值赋值给BYTE,导致数据丢失。 2、问题产生是由于查询第一种信道是TUP电路,但是却按ISUP电路查询。ISUP维护解决函数判断第一种信道不是ISUP信道,以为整个PCM不是ISUP类型PCM,返回所有电路状态为未安装。消息解决不合理。TUP也会产生如此错误。 【思考与启示】 咱们MML命令并不是无懈可击,许多表面上小问题,往往隐藏着代码缺陷和错误。 【案例1.6.2】 【正 文】 当咱们使用PC-LINT检查代码时,会发现大量数据类型不匹配告警,大某些状况下,这种代码上存在问题并不会引起程序功能实现上错误,但有些状况下,也许会产生严重问题: 一、不同数据类型变量之间赋值引起问题,事实上,该类问题也可以分为几种状况: 1、直接赋值,例如,把一种WORD型变量赋给一种INT型变量,如果WORD型变量不不大- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件 编程 规范 培训 实例 练习 样本
咨信网温馨提示:
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【二***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【二***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【二***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【二***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
关于本文