我们拒绝平庸,拒绝随波逐流,拒绝墨守成规,让梦想不再流浪。

C&C++编程军规

上一篇 / 下一篇  2014-06-23 15:53:41 / 个人分类:编程

军规条例

oO&[^&? a-oPc md051Testing软件测试网f`9sQ&a

2eJ$G m0D%I4z7ky9L6S0军规一:【禁止使用未经初始化的变量作为右值】

5A K.ozhq5k:r,r0

z wwGhmz1hqd0军规二:【禁止使用memset,memcpy直接对类实例进行初始化和拷贝】51Testing软件测试网w^ yD X+vK8M2B

51Testing软件测试网hc Rf| D7YX:JGY

军规三:【防止出现数组、指针内存访问越界,确保字符串以 ’\0’结束】

U7q8`3\N6G0

$ro(CpvpO h0军规四:【防止使用空指针和野指针】

$DW0Z*|o$l5K d0 51Testing软件测试网$?5zt~ g U

军规五:【及时释放内存,避免重复释放内存】51Testing软件测试网&f4`4B,V"Q9T,P%i~-[/S

51Testing软件测试网1c`)x)GRM6hA.c

军规六:【禁止返回函数中的局部变量的指针】

2[ x&`Ey R5n8E ~;`*q0 51Testing软件测试网 `S3mU'V7C

军规七:【防止类型转换溢出和精度丢失】51Testing软件测试网4Od/oM&SK$QgI x

51Testing软件测试网0Q vd2edKZ0Y

军规八:【多线程多进程访问共享资源时要防止重入和死锁】51Testing软件测试网8q$B0irzZW d9h%@

6TI3X\JC`0军规九:【头文件包含防止循环依赖,防止包含不同版本的头文件】51Testing软件测试网J?/T2Q,[?](V%k

.e0X"A R4Kn9h~,}-Y0军规十:【使用清晰简洁的表达式,加括号防止优先级混淆】51Testing软件测试网&A$y:g:@Pw9Ja$E

51Testing软件测试网$C5DJ,S&R1jbd`

51Testing软件测试网8r"IiWl2a g

4GGU5aY"w/b051Testing软件测试网,J YS:j,I9q

*uR Jd3t LG@L051Testing软件测试网0~ ~7n"W4Hh{X-sL/M


*K A Z*y`:j%S0 51Testing软件测试网p*XR.dJPwM

51Testing软件测试网r+?9U0d{m8_z

军规说明 51Testing软件测试网4r+z$i;N~ s3y LT'O

51Testing软件测试网!q-KN"_6pE

!|$xZ ?vz t e0军规一:【禁止使用未经初始化的变量作为右值】51Testing软件测试网5qw5W"U!QyE \1e.f.g0q

+BM4b$Pr(Uc9b E0包括全局变量,局部变量和类成员变量等,变量必须赋有意义的初值。51Testing软件测试网7E8Px {:iWbC7u3O4x

51Testing软件测试网,f7UA1nc'r9U8o

对于类成员变量,必须在构造函数或专门的初始化函数中进行初始化。51Testing软件测试网 s EvH(EA2t1Q

[F d.~)L0错误示例:

RF8zJJp\0 51Testing软件测试网$\!m5[4AM}

VOS_UINT8 udwVADOption; >>>修正方案:此处进行初始化赋初值 51Testing软件测试网/G*W:N6^u5D7A

51Testing软件测试网p3s^di r${(Ff8vkj

switch (ucRscType) 51Testing软件测试网 yWx+A8sL\B

nno4f)H2B*[[2Y0{

%vNKD4G7S2i)S$P0

%e RN0nuzD0case MRP_VPU_SUB_RSC_TC: 51Testing软件测试网DIa:v W+S

51Testing软件测试网Ty(R X7k

udwVADOption = g_stMrpAtcParaTblRec.udwVADOption; 51Testing软件测试网w6y6HtE'C

1M*M7D,U$CQKC,P0break; 51Testing软件测试网/C5i'b2v/V-r!x

GQ.K#z;vT_X k-?0case MRP_VPU_SUB_RSC_CC: 51Testing软件测试网1h5PJk1N0`

{3J_ |rO @0udwVADOption = g_stMrpCcParaTblRec.udwVADSwitch; 51Testing软件测试网8yW:? Q3|\3L0A_@:B

51Testing软件测试网`-T5m tO'e_D

break;

b#tX:ai0 51Testing软件测试网M|iTj L

default: --> 进default分支将导致相应的局部变量没有赋值 51Testing软件测试网Rvki]`n

51Testing软件测试网&V ? pq1| ~ u0z4A-k

/*目前没有其他资源支持*/

?vz%e2k7~C9W%E0 51Testing软件测试网J}/X;t4T^5w

break;

|g2ik |R|0

.n+VGv ]3Q0} 51Testing软件测试网w5JE6@ZO(?7g

5pCv+NZ$n0if (VOS_NULL_BYTE == pstIeInfo->ucVadPt)

o:qq&PmRWS ^\0

9D}9R+l8{{/^5@4g0{

3|(DyKr-TkTO0

;vxX}+W]9w.Ft0pstIeInfo->ucVadPt = udwVADOption; --> 这里使用就有问题了 51Testing软件测试网/{&j5`,Sc!a6jw

|!eXO Mr-BS&ru0}

:Q2{`wEH"[(@$_0 51Testing软件测试网mTJux1]8R|

详见:51Testing软件测试网c1Ur3oT A/cs5v

51Testing软件测试网 dP7D}%rh+a

《C规范》“规则4.3 严禁使用未经初始化的变量作为右值”,51Testing软件测试网yPg'v)yLA%Q

51Testing软件测试网 PX,J%M1DFE

《C++规范》“2.1 声明、定义与初始化”51Testing软件测试网g+x5J/Zi0A

51Testing软件测试网OUBM{#W*zi!\ w9V

军规二:【禁止使用memset,memcpy直接对类实例进行初始化和拷贝】51Testing软件测试网W5D1feQ\

51Testing软件测试网X/q'D!I"aB4o

C++的class必须实现对成员变量的具体操作。

[6_,^ c0@0

~/kD/DQv#T!H0POD(Plain Old Data)是普通旧式数据,如结构/枚举/成员指针等,内存字节是连续的。非POD对象的内存字节不连续,中间可能包含vptr(虚函数指针表)等隐藏的数据。

E5MO iE0 51Testing软件测试网+sGL2bN&g~

错误的做法:使用memset(this, 0, sizeof(*this)) 对初始化对象,vptr被破坏,赋为0。删除对象实例时,通过vptr指针访问析构函数,导致coredump51Testing软件测试网j,hm*JKI#Gt E

51Testing软件测试网i|F ?6f@2?

正确做法:取消memset操作,按照变量声明的顺序一个个初始化对象的成员变量。51Testing软件测试网2A G`;T*X8Y7Z z9\

51Testing软件测试网3~-\p y i Ik6?@

C++编译器经常会在多态对象中嵌入一些隐藏数据(如vptr),多重继承/虚拟继承会添加更多的内部指针。不要直接对C++的对象进行memset/memcpy等操作,应尽量使用类自身提供的赋值/复制功能。

P QY{GC7Sl:W,s9|0

!@'r cu9|7w0详见:51Testing软件测试网:@3C!vw$r?1^'}

H"b7K9A:@3fHM'J0《C++规范》“规则2.1 禁止用memcpy、memset初始化非POD对象”51Testing软件测试网M7l#\:Y'uH x

51Testing软件测试网!O%@(}&F5Y8g)N

军规三:【防止数组、指针内存访问越界,确保字符串以 ’\0’结束】

] tm'qVrT%_J7T"Q0 51Testing软件测试网'v4If@,b#W;h

数组、指针分配空间足够大小,操作时防止越界。51Testing软件测试网^!_@L+n"A*fL-Nc

51Testing软件测试网vO o-L8t&g

字符串要使用安全的函数来操作。

$@.B+@h1y m?$x0

OJ7\#y!@.y`^};P0错误示例: 51Testing软件测试网 l3]K0YP+?,D%|lir

X1PVh[0说明:opt->paramlen是信元长度,是可变长的。

-t-G d)~8j6@B%]0

{%KUT{/~g0VOS_MemCpy(stCallRefNum.number, opt->param, opt->paramlen);

:Sb.h^i%|0 51Testing软件测试网s/g re;d`jR-c|6o

修正方案:51Testing软件测试网~8G'ID_:I8j u

51Testing软件测试网 ~D ]9H9dRH5h[

先判断opt->paramlen长度,避免超过stCallRefNum.number长度。

e ]*d-Q%i3S,X0

8h SK8D4d"P0在转换时,代码会直接根据对信元长度进行内存拷贝操作;

RQ!O5b1~8W0 51Testing软件测试网+e'l5e]P Uux A

正常情况下,对局的信元长度是正常的,不会有问题。 51Testing软件测试网:jU7nu.S$?0W

51Testing软件测试网CEe2|8`;DJA z7KT

异常情况:如果长度超长,则会发生内存越界,导致故障。51Testing软件测试网K/_.^6h#?@8}

51Testing软件测试网f*SZ&MFtQOh&S

错误示例:

4VDlu2K4S!A"mb.P0

\C;NSt cx V3R0pErrMsgBuffer = VOS_Malloc(MODULE_ID_MAPPERDRV, dwBufSize + 1);

2N _5J`ZA0

|;O.?t-l6Q#ca0strncpy (pErrMsgBuffer, strErrMsg, dwBufSize); 51Testing软件测试网.TU)S ]s6V

51Testing软件测试网2f%InJny@

当源字符串长度超出dwBufSize时,strncpy拷贝dwBufSize长度的字符,但目标字符串的结尾没有被赋值为‟\0‟,以后引用字符串pErrMsgBuffer时可能出错。

9@(q'O8FJN-Z H[0 51Testing软件测试网Ieu~p+R

避免使用危险函数sprintf /vsprintf/strcpy/strcat/gets操作字符串,使用相对安全的函数snprintf/strncpy/strncat/fgets代替。

&`U!Csy!t$uH0 51Testing软件测试网)LMO$L l:IV;ic

详见:

KKZP)dI/R%cg0

jI9}AN:@;?pj;@w.G[0《C规范》“规则6.1 禁止内存操作越界”,“规则13.1 确保所有字符串是以NULL结束”51Testing软件测试网[(lu1q&f&~

51Testing软件测试网 c(h^/zB_c%bU4};`

军规四:【防止使用空指针和野指针】

EL o?n%i(v3x+W0 51Testing软件测试网 j8qEl#EnG

指针变量在赋值后、使用前要进行判空。

1]RN NcP t"g(} D0

s8h3I HEPs"Z0释放内存后,要立即将指针设置为空,防止产生野指针和访问已释放内存。

8xP_4W_:q4R-I%_-]-\0

;Eh"B|{ r(C4c0错误示例:

*yk \[7e0wp|Z-T0 51Testing软件测试网!rB@3H|u5D,K

void CSCP::AnalysisConnectRequest(CTI_RESOURCE_CONNECT_Msg* pMsg, CConnectNode* pNode,CConference* pOcuppyConf) 51Testing软件测试网$|h)K+KV~%c

mK6`.QG%q5R1Ko0{

|&e2rjF-L0 51Testing软件测试网{CS+?+cv

CConnectObject* pObject = NULL;

J)`&t'j J;N0 51Testing软件测试网Uq;?_&k/g

... ... 51Testing软件测试网rE\.U#D)I9d*k

5K+B&_s.Y J0if(pSourceObject != NULL && pDestObject != NULL) { 51Testing软件测试网1_o7NuTe;E#l7A/E*Iu

*K H`,N w5iz2m0if(!pSourceObject->IsConference() && !pDestObject->IsConference()) {

dMw8Ott{3X0 51Testing软件测试网u4q.b*V~V3b

CConference* pDevice = pOcuppyConf;

7t#p4k6N{0 51Testing软件测试网g,b4Hi:wD1@U|

if(CONN_CONF_REQUEST==pObject->m_ucCurConnectContext) //使用指针时没有检查,导致使用空指针

6g9uFZR0 51Testing软件测试网{,Zy BQ j

修正方案:先给pObject做有效性判定再使用,如:赋初始值。

`,j}c(o:k5^&f0 51Testing软件测试网w#|,`)zh.\S%A&s

错误示例: 指针托管后被误delete51Testing软件测试网-e r c*m*?1lI1s

#x m,ye ]Mx1m0NEW(pSession, CSubscribeSessionInfo);51Testing软件测试网Q^C*L|9j^Q

?)ki1][Y9t$@s0CSessionProcessMgr::instance()->event(pSession->getSessionType(), pSession, code);

+te4OU%Q`(mxVv0 51Testing软件测试网V;s4HDI"_'qs+sf

m_pSessionControl->addSession(pSession)

&N:Bfy'DK BzB/N0 51Testing软件测试网/Q.Fo |^.Y6K

//上面event处理完了有可能会话已结束

?U L R3odh0

4OG+EU bSjg A/a;O0if (pSession->isSessionOver())51Testing软件测试网&V3o^t5H1fTlM

V^LOJd] Z8y0{

x2Q(yH[S.c9b0 51Testing软件测试网M%Zru-J4_.V

DELETE(pSession);//此时delete,那么托管的指针指向内存就被误释放了51Testing软件测试网~o{%Cd L

,E1bF%A-[C(o0return;51Testing软件测试网J)iPc%z+ro

51Testing软件测试网RU)D6Hf

}51Testing软件测试网 t-`8a4Nj*l${([u

51Testing软件测试网}8p4r#t K&WLl

修正方案: 51Testing软件测试网_l6ez%G ErQ:v#E3d

PKw~z,oG0if (pSession->isSessionOver())51Testing软件测试网q bT WW)u|I

51Testing软件测试网8S#\[#g['? x

{51Testing软件测试网,WW~wh9dW H

51Testing软件测试网7B\Dz B#IB

m_pSessionControl->removesession(pSession);51Testing软件测试网*Bj%i~;i

#Q)|a4T@(K ~ WO,n$G0return;51Testing软件测试网 w#R4t^;y CFU~

KF8N I^8C!o%i0}51Testing软件测试网1vl;u+|a"CH$S?eY

mdqe^ [B0详见:

Ex~cwccV.w0 51Testing软件测试网*^y%{/xFIk H3d

《C规范》“规则6.3 禁止引用已经释放的内存空间”,《C++规范》“规则6.2 释放内存后,要立即将指针设置为NULL,防止产生野指针”51Testing软件测试网6n6G6s0mL-Y:^I

51Testing软件测试网2k8zo!b4V[E\

军规五:【及时释放内存,避免重复释放内存】

6[ JQ0L@A0

O%V Cb [ `&F&U0尽量避免跨函数分配和释放,尽量避免跨类分配和释放。若因设计的需要跨作用域进行分配和释放,必须重点评审,禁止出现忘记释放导致内存泄漏,禁止重复释放。51Testing软件测试网QF"\%o1z~

yGbQT;X0错误示例: 指针托管后重复delete51Testing软件测试网w*`0z)p!r-A

51Testing软件测试网&ht-}C;b,c;I3L

NEW(pLogMsg)51Testing软件测试网'U7qGl _2m

"o%u5P*M9[T6q7k0//…

)o b.PG8v0 51Testing软件测试网u'su?n |;Og

if (false == app.postMsg(pLogMsg))

)pZ2s;P9K UY0 51Testing软件测试网_o/W0B Gh3N/U3|

{51Testing软件测试网)u @ opp dm-C0v

e8bZ5[ c"N!AXA7O0//…51Testing软件测试网Aiv/GI Jv

%I'` m7Sl0UO0DELETE(pLogMsg);51Testing软件测试网}(@*y6m2wx8xB%j

\;iFv_3h t4V]-z0}

'E2a3H j5U Yzk0

7Je7umkY0TBool Application::postMsg(InnerMsg* pMsg)51Testing软件测试网6[j"V"x8Zk

51Testing软件测试网#`!h ol:N4X

{

$@.y5GZ]H0

2n jYhYJv |"D6E0if (false == dispatch(pMsg))

:X&c$VUW|8] \0 51Testing软件测试网@ };n:Z;f7\LHj

{51Testing软件测试网ug*jl6K%E@

+g2ki n%]A0//…51Testing软件测试网%Zda-N}2D9l

51Testing软件测试网/G1CU`)i6o/a.QMw)d

DELETE(pMsg);

x@#iSw+tQE0

NO u-L(G,HV0return False;51Testing软件测试网 m|7R\n1G

&_h&y*{ b0}

1l0H-},A*p{Z X v-`-K+u0 51Testing软件测试网 {$q@Ii+o`w

//...

9m8KK F:V)[p0

pdVz&\ l0}51Testing软件测试网2|d(p~}yg

m Co&w&dC mzg0修正方案: 统一释放原则。51Testing软件测试网/F4zS&}r;z

51Testing软件测试网g v`UcK

TBool Application::postMsg(InnerMsg* pMsg)

wduT!ig }M0

9Y\ E(x [n0{

+x8YU#I"u%h p]kt0

IdI0f w{"^0if (false == dispatch(pMsg))51Testing软件测试网7[\P F8E

51Testing软件测试网`!Y8XbDR,z9?

{51Testing软件测试网0{"F%tw(l(n |cA

'C,[YS6ov;i0//…

+^9H [H Z U?0

(t oc;~[8D)r0DELETE(pMsg);

'JL3p)~9BzP0\+Q w0 51Testing软件测试网L1h3_5EU

return False;//托管失败时由上面的申请内存的函数负责释放

2_8O;j-OY/H$D,P0

v'h ^G rU1I7D*{F4[ N0}51Testing软件测试网7Hd,xc%Xz2oe

a I"Q:c9}(X0//...51Testing软件测试网*RH8K G%U DT`tm"X5{

51Testing软件测试网0Sh1^bs;i+Df?8R*F4w

}51Testing软件测试网w^4ry$~mA7N

^P8p'JC.]0详见:

?_EG LpH,z0

"h/m^!\2}2fg0《C规范》“规则6.2 禁止内存泄漏”,

%Y!?8o!B0^{0 51Testing软件测试网Ofy-t,R1S

《C++规范》“规则6.3 单个对象释放使用delete,数组对象释放使用delete []”“规则6.4 释放结构(类)指针时,首先释放其成员指针的内存空间”“规则6.5 释放指针数组时,首先释放数组每个元素指针的内存”51Testing软件测试网e1rs2]N4Fg

L#p#Y)?7z0军规六:【禁止返回函数中的局部变量的指针】51Testing软件测试网)x}2FUX%p}[

51Testing软件测试网@-k'{f+L5hP

不得将函数中局部变量的地址或指针作为返回值。

BqVi$P&J6A"Bz0 51Testing软件测试网#Vg!Q2l)q$W ~

错误示例:51Testing软件测试网RA`3K D `;yqQ

51Testing软件测试网j8g"b8HLB}i

char* GetParameter ()51Testing软件测试网:l KdN,?

(Y Wp!Nx:A0{51Testing软件测试网 w^$_V_

51Testing软件测试网 X'Bi;U"sf|i ~

CDBConnect DBConnect;51Testing软件测试网!u h3p)xa4Y.v

51Testing软件测试网f}#b4qf:C:R'v

//………………..

.N3LO5M(z Eg0 51Testing软件测试网b,y;ug#nU F

return DBConnect.GetString("ParamValue");

L4S!bkR y4Y8y0 51Testing软件测试网Q"dh3SW Wb ~ t

}

"O8kx F/B0 51Testing软件测试网$g P_ [~H i

修正方案:返回一个副本

@ O4ABb)ER&l0

9t:z q;L8S H4Ni4I7D0String GetParameter ()

I ]7i7CR{0 51Testing软件测试网)]c K'mvJ$_te

{51Testing软件测试网J2v%UT@P:@v

d)m v@v,l ]*p4x0CDBConnect DBConnect;

[{,| P5@n T~0 51Testing软件测试网5iE3h#WJ

//………………..51Testing软件测试网 Y;|EJv`

A|X1b!UKDb qc7B0return String( DBConnect.GetString("ParamValue") );

"L2Y(AB#?d\0R0 51Testing软件测试网,Sk!pn8{*z"a0z$d

}

%Ze)yp.x.ye{P0

9v lhNF z0详见:

.fJu is+|uI0

!h'[@\Y VL2n/d_SfO0《C++规范》“规则6.6 不要返回局部对象指针”51Testing软件测试网'nCk X2m3a+~

51Testing软件测试网A Q`IU{2\"G

军规七:【防止类型转换溢出和精度丢失】51Testing软件测试网Rd,uNT1o1c#V#rS.z;]

51Testing软件测试网ZM H1n9L

防止无符号数运算溢出,数据类型转换时精度丢失。

FA\EdhV:K0 51Testing软件测试网e9T0EQ,{\jZ

尽量避免不必要的类型转换。

/sf$Gd9T&E}y'c.D,V?0

q`4U Q%lm"`u0C++新增代码使用static_cast等C++风格的类型转换,以便于排错。51Testing软件测试网p NS%G1Z

[R(R zvv/N0错误示例:51Testing软件测试网J]_P l

51Testing软件测试网F(s'FetF*B9S

uiLargeNumber = GetLargeNumber();

D:|8p @V@7{0

G4e]u8Xaql z0uiSmallNumber = GetSmallNumber();51Testing软件测试网MAtwm \

unU kJ8K:c0unsigned int uiLow = uiLargeNumber - uiSmallNumber; //错误,无法保证uiLargeNumber一定比uiSmallNumber大。

u|p4Msmte]f0 51Testing软件测试网7uS?[9p8U

修正方案: 51Testing软件测试网7SW4J/E2a&yy;{ p

51Testing软件测试网-^%oH4`!wu6l

uiLargeNumber = GetLargeNumber();

\d(@q0U^0

H"WlI J$nk0uiSmallNumber = GetSmallNumber();51Testing软件测试网1H&r ~ l/egj

[.W7N'F aG-r$o0if (uiLargeNumber > uiSmallNumber) //正确,先判断好范围。51Testing软件测试网j%RdV E\5L} N q5j

51Testing软件测试网*Br JQ:J

{

\3m X[|8m HEO H0 51Testing软件测试网 C:Ny%j2G VD

uiLow = uiLargeNumber - uiSmallNumber;51Testing软件测试网 [9sWD]G2}

?X!r2`&w5Lx"`0}

a;],]bl%k/P4w8s(i0

B*|8],J#{_5c{0else51Testing软件测试网3q ^$^ZB4S?)}'v1ZV

|~ s3^2\0k0{

luK#]'F h0 51Testing软件测试网#S%v d[A)uIy0m[/`

uiLow = 0;

;c2C4jHdDg;A;p0

z wW$q J*['`HL)Y0}51Testing软件测试网g;{ ]S&f k(zj/W

U?z"J-}qo9[0详见:

PY2Bwa5}}0h$LK0 51Testing软件测试网#t:l#^0t,w-Bo

《C规范》“规则13.3 避免整数溢出”,“规则13.4 避免符号错误”,“规则13.5:避免截断错误”, 51Testing软件测试网 lq ]G;{

R1B E&v$J![ w$C0《C++规范》“规则2.2 使用C++风格的类型转换,不要使用C风格的类型转换” 51Testing软件测试网 h"g9m(J/Qy

$}^m/m| lS0军规八:【多线程多进程访问共享资源时要防止重入和死锁】51Testing软件测试网]ws N q `@ |;Q/A

51Testing软件测试网 \[gp2q}|#Z

加锁注意不要遗漏程序分支,C++代码可以采用guard方法。

2a0N|"} Hl"]0

5f1r(~?7I*v0注意使用线程安全函数。

w'S l}&}F"k0 51Testing软件测试网b,onH&G/`%^ x\RON

错误示例:

o$@EW9u4d0

5}7g5w$Ghn D3|+X)P0//g_Exam是int型全局变量,函数Squre_Exam返回Exam平方值。那么如下函数不具有可重入性。 51Testing软件测试网z%zMK!N

51Testing软件测试网 Zq6Xs$\#pF+f8CN6}

...... 51Testing软件测试网([aE-[(upsf

51Testing软件测试网&@ x/V;{BM:@rf

int g_Exam;

vanJ(c*O%Z;n!|0 51Testing软件测试网*Z-iq A}'i8D9V

unsigned int example( int para )

tb6z bu7qB|0

I&p!Gg'r6{6m-^B0{

c[-L)J"R?0

Q$E7~3C%_0unsigned int temp;

[{{UP%] N0

N7u"k k5x0g_Exam = para; // (**)

o#O1o5~:f A:{}9C0 51Testing软件测试网z#q#c6N Q'A f

temp = Square_Exam(g_Exam);

H`b#I1]%M0 51Testing软件测试网$i5lK%} ejfB

return temp;

y*\ d'zM7Y_ })T0

Yw'qUC0}

%S0c;?4x}{G*l}/M0

u3~ yYH\l0......

7aj"o7v?6v[e0 51Testing软件测试网C3U&Xi"w4S"?3H

正确示例:

` s#ax/_0 51Testing软件测试网|lQK'bioPN(b

...... 51Testing软件测试网 W fY_K

51Testing软件测试网9IlFy3iL-q&]5W

int g_Exam; 51Testing软件测试网8o-N xl0zI#lF A

^Qa+tM6o9?!D0semaphore smMutex = 1; /* 控制互斥访问的信号量 */

*WiP1lCHSsq0 51Testing软件测试网iv,{1~Bie'C

......

%njW$j SX'}$_j0

9rP[N8e/Y_`}0unsigned int example( int para )

/A9HTS9c_0

/D7Uv$Z)}y\*x2H V?0{

#EZ|uh0K&[h v A0 51Testing软件测试网Xz8q0Ja

unsigned int temp; 51Testing软件测试网 W YFZ:Fg'|Ii

*xOp\ W o@2o2`0P(smMutex); // 若申请不到“信号量”,说明另外的任务正处于给Exam赋值并计算其平 51Testing软件测试网 x rr4^'bC^1iN

2K f;qgA`9SKrky0g_Exam = para; // 方过程中(即正在使用此信号),本任务必须等待其释放信号后,才必须等待本

%s glr%yK0 51Testing软件测试网*B.@5M9Y,MW(l[/c

V(smMutex); // 任务释放号量后,才能再使用本信号。 51Testing软件测试网;aXCnk]kw~

wV1r H;dL+W+Zj0return temp;

z9r^&M O9C3Hg&pj0

\&q\{]4WM r0}51Testing软件测试网h$Ob%J qr

-@%Idt-ul| lN S0详见:51Testing软件测试网tS8[R d.u3u

6cLB i_ rDV0《C++规范》“规则10.1 多线程、进程并行访问共享资源时,一定要加锁保护”,“规则10.3 锁范围尽量小,只锁对应资源操作代码”,“规则10.4 避免嵌套加锁” 51Testing软件测试网d fW9j ]2\

51Testing软件测试网(k5] `s B,k$EU

军规九:【头文件包含防止循环依赖,防止包含不同版本的头文件】51Testing软件测试网 p,X hi9v O,L9o

at?2{ |];n6_2W0头文件包含层次清晰,去掉不必要的包含与重复包含,需要提供外部使用的接口才放到头文件中。51Testing软件测试网U&{Ki7h#AZ3j

51Testing软件测试网d0Co%m ]#qt

防止包含不同版本的API头文件,以免导致不必要的运行错误。51Testing软件测试网~Qf'_H Au2}6Y?

%B L9qIc5B)u&q%h0详见:

]jkg*se0 51Testing软件测试网;d2[D.@/o H

《C规范》“规则1.1 每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口”,“规则1.2 禁止头文件循环依赖”,“规则1.3 .c/.h文件禁止包含用不到的头文件”

v#i5z.GN?5x C'`0

6Il2T.x U8t2e*l.K0军规十:【使用清晰简洁的表达式,加括号防止优先级混淆】51Testing软件测试网o3M X(RBN

Z`T@d8e2her0注意运算符的优先级,并用括号明确表达式的操作顺序。51Testing软件测试网;JR c%HR

9C+zWH|s0错误示例:

c5O0Vm K7h*q8H0 51Testing软件测试网eN@2UiR6j

……

?C8q+Y2^rdfu Mz0 51Testing软件测试网)hf$qb {$EO

if ((sqn.seq2 + 1) & 0x01000000 > 0) {

5{x_}h0 51Testing软件测试网5a;{ r OkJ`Z

……

9az \1J.E:\C0 51Testing软件测试网 gc V%] f'tU z

}

/q8nL8zh2t3tC;Y0

Y0Yb^:b(S I0q0pn:U0……

m9f1M$w4?Yr7_X8n;k0 51Testing软件测试网o? Z ij7F

由于>运算符优先级大于&, 上述if语句恒成立。51Testing软件测试网+Wh8|su&k

51Testing软件测试网/n*m ^c}$d

正确示例:

kd-i4o5C{)Cf0 51Testing软件测试网o}7K*et| H

……

6S6R@ N5W(I ` W.T0

vm w+p|oD0if (((sqn.seq2 + 1) & 0x01000000 ) > 0) { // 加括号

x |3[4lemv\g0

[ M\u"{u0……

zb(|SM0 51Testing软件测试网[%]-qnfx3_

} 51Testing软件测试网)h`-\T tu0C1b

5F;?e/?R6T0……51Testing软件测试网3KY F+kf!Y w

#u} { `jR0尽量避免使用复杂的表达式,除非性能要求,最好拆成几个语句。

%c)eC)[1?o/`[ybxm0

TAG:

 

评分:0

我来说两句

日历

« 2024-04-15  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 109268
  • 日志数: 89
  • 图片数: 1
  • 文件数: 15
  • 建立时间: 2013-03-01
  • 更新时间: 2018-08-23

RSS订阅

Open Toolbar