




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2023/2/1C语言软件编程规范工作组公司常见软件编程低级错误:表达式前言这套材料作为编程规范的辅助材料,帮助大家理解编程规范背后的原理。C和C++语言是我司的主流编程语言,然而C/C++具有很多强大的语言特性,从而导致C/C++非常复杂,使得代码更容易出现BUG、难以阅读和维护。业界知名的编程规范都对C/C++容易出现问题的语言特性进行管理。例如MISRA(汽车工业软件可靠性联合会)制定的1998版的MISRAC规范指出,一些在C看来可以接受,却存在隐患的地方有127处之多。2004版的MISRAC规范将针对C语言的规则增加到了141条。对于程序员来说,能工作的代码并不等于“好”代码。“好”代码的指标很多,包括可读性、可维护性、可移植性和可靠性等。出现网上问题的代码,大多数是不良编程习惯引起的。不遵守编程规范的代码,往往也是最不可靠的代码。本胶片收集了常见的表达式案例,给出了相应的纠正措施。对应的编程规范:表达式的值在标准所允许的任何运算次序下都应该是相同的;用括号明确表达式的操作顺序,避免过分依赖默认优先级表达式使用默认优先级:规则【规则】ISO9899:1990的6.5.4节对使用括号的建议:1.一元运算符,不需要使用括号
x=~a; /*一元运算符,不需要括号*/x=-a; /*一元运算符,不需要括号*/2.二元以上运算符,如果涉及多种运算符,则应该使用括号x=a+b+c; /*运算符相同,不需要括号*/x=f(a+b,c) /*运算符相同,不需要括号*/if(a&&b&&c) /*运算符相同,不需要括号*/x=(a*3)+c+d;/*运算符不同,需要括号*/x=(a==b)?a:(a–b);/*运算符不同,需要括号*/3.即使所有运算符都是相同的,如果涉及类型转换或者量级提升,也应该使用括号控制计算的次序以下代码将3个浮点数相加:f4=f1+f2+f3;/*除了逗号(,),逻辑与(&&),逻辑或(||)之外,C标准没有规定同级运算符是从左还是从右开始计算,以上表达式存在2种计算次序:f4=(f1+f2)+f3或f4=f1+(f2+f3),浮点数计算过程中可能四舍五入,量级提升,计算次序的不同会导致f4的结果不同,以上表达式在不同编译器上的计算结果可能不一样,建议增加括号明确计算顺序*/表达式使用默认优先级(1)【问题描述】同一个目录下发布多个频道到一定值后,虽然是计费频道,但实际访问时并没有付费定购提示,好像变成了免费模式【问题定位】问题代码如下:StringcurDirPosition=(longCurDirPosition%100>9)?"":"0"+longCurDirPosition%100;程序的本意是根据longCurDirPosition%100>9的值,输出”longCurDirPosition%100”或者””0”+longCurDirPosition%100”。在换行符的作用下很容易让人以为程序是没有问题的,但实际上程序执行的优先级与作者的期望不符,以上语句等价与:StringcurDirPosition=(longCurDirPosition%100>9)?"":("0"+longCurDirPosition%100);结果将输出””或者”’0’+longCurDirPosition%100”【纠正措施】补充一对括号,修改代码为:StringcurDirPosition=((longCurDirPosition%100>9)?"":"0“)+longCurDirPosition%100;表达式使用默认优先级(2)【问题描述】对密码进行MD5加密的时候,得出来的结果每次都是空。【问题定位】如下代码:ucPwdLen=ucPwdLen&0xf0+0x10;程序执行的实际优先级为:ucPwdLen=ucPwdLen&(0xf0+0x10);【纠正措施】补充一对括号,修改代码为:
ucPwdLen=(ucPwdLen&0xf0)
+0x10;表达式使用默认优先级(3)【问题描述】香港鉴权二次重同步出现SQN混乱。【问题定位】如下代码:if((sqn.seq2+1)&0x01000000>0){……….}由于>运算符优先级大于&,
程序执行的实际优先级为:if((sqn.seq2+1)&(0x01000000>0))
上述if语句恒成立,导致SQN混乱。【纠正措施】补充一对括号,修改代码为:
if(((sqn.seq2+1)&0x01000000)>0)
表达式副作用:移植后出错【问题描述】产品移植到新平台后,下发某命令,配置不成功。【问题定位】问题代码如下:Set_Config_Table(DB_Query(),Get_Next_WD());原来的平台编译器先执行Get_Next_WFD(),后执行DB_Query(),结果正确;新的平台编译器先执行DB_Query(),后执行Get_Next_WD()。在这两个函数中,都读写了全局变量g_MuxData,所以两种计算次序的执行结果不一样。【纠正措施】明确语句执行次序,函数参数不再使用表达式:intnWDID=Get_Next_WD();intnDBID=
DB_Query();Set_Config_Table(nDBID,nWDID);表达式副作用:定义【定义】副作用(side-effect)指执行后对程序运行环境造成影响,除了无效代码外,C/C++的每条语句要么使程序流程改变,要么产生副作用。每个表达式都产生一个值,同时可能包含副作用(例如将产生的值赋给一个变量)。在C/C++语言中,表达式副作用是必须而且有意为之的,但C/C++要求表达式副作用必须在sequencepoint之前结束;在两个连续sequencepoint之间,一个对象所保存值最多只能被修改一次;如果对象的值被修改了一次,那么表达式中出现此对象的唯一目的只能是为了求出这个被修改的新值。否则可能产生非预期结果。sequencepoint是一个结算点,编译器在此点完成所有计算。C/C++语言定义的sequencepoint如下:函数参数计算完成后,调用之前有一个sequencepoint&&||和?,这三个运算符的左侧有一个sequencepoint逗号运算符左侧有一个sequencepoint(注意逗号作为分隔符使用时没有sequencepoint)分号左侧有一个sequencepoint完整表达式(ifswitchwhilereturn等里面的表达式)【注意】运算符优先级只在一个表达式中有效,两个表达式之间如果没有一个sequencepoint,那么先计算A表达式,还是先计算B表达式,次序不定。有时,2个sequencepoint也不保证顺序执行。表达式的非预期副作用一般不能通过增加括号消除。不确定计算次序是有意保留给编译器进行优化的。【要求】表达式非预期副作用主要表现在使用复合表达式上,如果将复合表达式分开写成若干个简单表达式,就可以有效消除非预期副作用。++/--等操作符本身包含副作用(赋值功能),所以最好单独一行。表达式副作用:规则(1)【规则】ISO9899:1990的5.1.2.3节,6.2节,6.3节和6.5节描述了可能产生非预期副作用的计算:1。自增或自减运算符:a[i]=i++;上面的表达式当中没有sequencepoint,i的值只被修改了一次,表达式i++的目的是求出i的新值,但a[i]却与求i值无关。所以计算结果不确定。这样的代码本质上是非法的,但不产生编译告警,大多数情况下也没有PCLint告警。类似的代码还有:i=0;i=i++;/*i与求i值无关,结果是0,1,或其它任意值,与编译器相关*/i=0;printf(“%d%d“,i,i++)/*i与求i值无关,结果是0,1,或其它任意值,与编译器相关*/2。函数指针函数参数和函数自身地址的计算次序未定义。p->task_start_fn(p++);求函数地址p与计算p++无关,结果是任意值。必须单独计算p++:p->task_start_fn(p);p++;表达式副作用:规则(2)3。函数调用x=f(a)+g(b);编译器可能先计算f(a),也可能先计算g(b),如果x的结果依赖于函数f/g的计算次序(例如,f/g被调用时修改或使用了同一个全局变量),则上面的代码存在问题。应该修改代码明确f/g的计算次序:x=f(a);x=x+g(b);4。函数参数函数参数通常从右到左压栈,但函数参数的计算次序不一定与压栈次序相同。x=func(i++,i);应该修改代码明确先计算第一个参数:i++;x=func(i,i);前面曾经举的网上问题案例也是类似的代码:Fun(shared_ptr<Widget>(newWidget),shared_ptr<Widget>(newWidget));Set_Config_Table(DB_Query(),Get_Next_WD());表达式副作用:规则(3)5。嵌套赋值语句表达式中嵌套赋值语句可能导致某些对象被赋值多次,导致结果不确定。例如,如下代码中x被赋值了2次(编译器:VC6.0):(x=y)=z;6。volatile访问限定符
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025初三升高一数学暑假衔接讲义25讲含答案(必修一内容)3.5.4 恒成立和存在性问题含答案
- 2025年中考语文一模试卷
- 测评依据22课件
- 苯环亲电取代的定位规律54课件
- 考研复习-风景园林基础考研试题附参考答案详解【完整版】
- 考研复习-风景园林基础考研试题(真题汇编)附答案详解
- 风景园林基础考研资料试题及参考答案详解【培优】
- 《风景园林招投标与概预算》试题A带答案详解ab卷
- 2023年上海市上海市松江区佘山镇招聘社区工作者真题附详细解析
- 2024年山东华兴机械集团有限责任公司人员招聘笔试备考题库及参考答案详解一套
- 2023年山东省济南市高新区中考物理一模试卷(含解析)
- 工程质量保证措施
- 环保知识试题-环保知识试题及答案
- 刘醒龙文集:生命是劳动与仁慈
- 探寻中国茶一片树叶的传奇之旅2023章节测试答案-探寻中国茶一片树叶的传奇之旅超星尔雅答案
- 预制管桩吊装方案
- 2023年版一级建造师-水利工程实务电子教材
- GB/T 39936-2021深冷保冷用泡沫塑料
- 国家开放大学电大《课程与教学论》形考任务3试题及答案
- 社会治安综合治理课件
- alphacam使用教程文档
评论
0/150
提交评论