Tải bản đầy đủ - 0 (trang)
Chapter 30.  Avoid overloading &&, ||, or , (comma)

Chapter 30.  Avoid overloading &&, ||, or , (comma)

Tải bản đầy đủ - 0trang

Summary

Wisdommeansknowingwhentorefrain:Thebuilt-in&&,||,

and,(comma)enjoyspecialtreatmentfromthecompiler.Ifyou

overloadthem,theybecomeordinaryfunctionswithvery

differentsemantics(youwillviolateItems26and31),andthis

isasurewaytointroducesubtlebugsandfragilities.Don't

overloadtheseoperatorsnaùvely.



Discussion

Theprimaryreasonnottooverloadoperator&&,operator||,

oroperator,(comma)isthatyoucannotimplementthefull

semanticsofthebuilt-inoperatorsinthesethreecases,and

programmerscommonlyexpectthosesemantics.Inparticular,

thebuilt-inversionsevaluateleft-to-right,andfor&&and||

alsouseshort-circuitevaluation.

Thebuilt-inversionsof&&and||firstevaluatetheirleft-hand

expression,andifthatfullydeterminestheresult(falsefor&&,

truefor||)thentheright-handexpressiondoesn'tneedtobe

evaluatedandisguaranteednottobe.Weallgetsousedtothis

handyfeaturethatweroutinelyallowthecorrectnessofthe

right-handsidedependonthesuccessoftheleft-handside:

Employee*e=TryToGetEmployee();

if(e&&e->Manager())

//



Thiscode'scorrectnessreliesonthefactthate->Manager()will

notbeevaluatedifeisnull.Thisisperfectlyusualand

fineunlessthe&&usedisanoverloadedoperator&&,because

thentheexpressioninvolving&&willfollowfunctionrules

instead:

Functioncallsalwaysevaluateallargumentsbefore

execution.

Theorderofevaluationoffunctionargumentsis

unspecified.(SeealsoItem31.)



Solet'slookatamodernizedversionofthesnippetabovethat

usessmartpointers:

some_smart_ptre=TryToGetEmployee();

if(e&&e->Manager())

//



Now,saythiscodehappenstoinvokeanoverloaded

operator&&(providedbytheauthoreitherofsome_smart_ptr

orofEmployee).Thenthecodewillstilllookfinetothereader,

butwillpotentially(anddisastrously)calle->Manager()whene

isnull.

Someothercodewon'tdumpcoreeveninthepresenceofsuch

eagerevaluation,butbecomesincorrectforadifferentreasonif

itdependsontheorderinwhichthetwoexpressionsare

evaluated.Theeffects,ofcourse,canbejustasharmful.

Consider:

if(DisplayPrompt()&&GetLine())

//



Ifoperator&&isauser-definedoperator,itisunspecified

whetherDisplayPromptorGetLineiscalledfirst.Theprogram

couldinadvertentlyendupwaitingforinputfromtheuser

beforedisplayingtheexplanatoryprompt.

Ofcourse,suchcodemayseemtoworkwithyourcurrent

compilerandbuildsettings.It'sstillfragile.Compilerscan(and

do)choosewhateverordertheyfindfitbestforanyparticular

call,takingintoaccountconcernssuchasgeneratedcodesize,

availableregisters,expressioncomplexity,andsoon.Sothe

samecallmightbehavedifferentlydependingonthecompiler



version,thecompilerswitchsettings,andevenonthe

statementssurroundingthecall.

Thesamefragilityoccurswiththecommaoperator.Like&&and

||,thebuilt-incommaguaranteesthatitsexpressionswillbe

evaluatedleft-to-right(unlike&&and||,italwaysevaluates

both).Auser-definedcommaoperatorcannotguaranteeleft-torightevaluation,usuallywithsurprisingresults.Forexample,if

thefollowingcodeinvokesauser-definedcommaoperator,itis

unspecifiedwhichofforgreceivesthevalue0andwhich

receivesthevalue1.

inti=0;

f(i++),g(i++);//seealsoItem31



Examples

Example:Initializationlibrarywithoverloadedoperator,for

sequenceinitialization.Onelibraryhelpfullytriedtomakeit

easiertoaddmultiplevaluestoacontainerinoneshotby

overloadingthecomma.Forexample,toappendtoa

vectorletters:

set_cont(letters)+="a","b";//problematic



That'sfineuntilthedaythecallerwrites:



set_cont(letters)+=getstr(),getstr();//orderunspecifiedw



Ifgetstrgetsuserconsoleinput,forexample,andtheuser

entersthestrings"c"and"d"inthatorder,thestringscan

actuallybeappliedineitherorder.That'sasurprise,because

thisisnotaproblemforthebuilt-insequencingoperator,:



strings=getstr(),getstr();//orderwell-specifi



Exceptions

Anexceptionisexpressiontemplatelibraries,whichbydesign

capturealloperators.



References

[Dewhurst03]Đ14[Meyers96]Đ7,Đ25[Murray93]Đ2.4.3

[Stroustrup00]Đ6.2.2



31.Don'twritecodethatdependsonthe

orderofevaluationoffunction

arguments

Summary

Discussion

References



Summary

Keep(evaluation)order:Theorderinwhichargumentsofa

functionareevaluatedisunspecified,sodon'trelyonaspecific

ordering.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 30.  Avoid overloading &&, ||, or , (comma)

Tải bản đầy đủ ngay(0 tr)

×