Tải bản đầy đủ - 0 (trang)
Chapter 70.  Distinguish between errors and non-errors

Chapter 70.  Distinguish between errors and non-errors

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

Summary

Abreachofcontractisanerror:Afunctionisaunitofwork.

Thus,failuresshouldbeviewedaserrorsorotherwisebasedon

theirimpactonfunctions.Withinafunctionf,afailureisan

errorifandonlyifitviolatesoneoff'spreconditionsor

preventsffrommeetinganyofitscallees'preconditions,

achievinganyoff'sownpostconditions,orreestablishingany

invariantthatfsharesresponsibilityformaintaining.

Inparticular,hereweexcludeinternalprogrammingerrors(i.e.,

wherethecallerandcalleearetheresponsibilityofthesame

personorteam,suchasinsideamodule),whichareaseparate

categorynormallydealtwithusingassertions(seeItem68).



Discussion

Itiscrucialtocrisplydistinguishbetweenerrorsandnon-errors

intermsoftheireffectsonfunctions,especiallyforthepurpose

ofdefiningsafetyguarantees(seeItem71).Thekeywordsin

thisItemareprecondition,postcondition,andinvariant.

Thefunctionisthebasicunitofwork,nomatterwhetheryou

areprogrammingC++inastructuredstyle,anOOstyle,ora

genericstyle.Afunctionmakesassumptionsaboutitsstarting

state(documentedasitspreconditions,whichthecalleris

responsibleforfulfillingandthecalleeisresponsiblefor

validating)andperformsoneormoreactions(documentedas

itsresultsorpostconditions,whichthefunctionascalleeis

responsibleforfulfilling).Afunctionmayshareresponsibilityfor

maintainingoneormoreinvariants.Inparticular,anonprivate

mutatingmemberfunctionisbydefinitionaunitofworkonits

object,andmusttaketheobjectfromonevalidinvariantpreservingstatetoanother;duringthebodyofthemember

function,theobject'sinvariantscanbe(andnearlyalwaysmust

be)broken,andthatisfineandnormalaslongastheyare

reestablishedbytheendofthememberfunction.Higher-level

functionscomposelower-levelfunctionsintolargerunitsof

work.

Anerrorisanyfailurethatpreventsafunctionfromsucceeding.

Therearethreekinds:

Violationof,orfailuretoachieve,aprecondition:The

functiondetectsaviolationofoneitsownpreconditions

(e.g.,aparameterorstaterestriction),orencountersa

conditionthatpreventsitfrommeetingapreconditionof

anotheressentialfunctionthatmustbecalled.

Failuretoachieveapostcondition:Thefunctionencounters



aconditionthatpreventsitfromestablishingoneofitsown

postconditions.Ifthefunctionhasareturnvalue,producing

avalidreturnvalueobjectisapostcondition.

Failuretoreestablishaninvariant:Thefunctionencounters

aconditionthatpreventsitfromreestablishinganinvariant

thatitisresponsibleformaintaining.Thisisaspecialkind

ofpostconditionthatappliesparticularlytomember

functions;anessentialpostconditionofeverynonprivate

memberfunctionisthatitmustreestablishitsclass's

invariants.(See[Stroustrup00]ĐE.2.)

Anyotherconditionisnotanerrorandthereforeshouldnotbe

reportedasanerror.(SeeExamples.)

Thecodethatcouldcauseanerrorisresponsiblefordetecting

andreportingtheerror.Inparticular,thecallershoulddetect

andreportwhenitcannotmeetato-be-calledfunction's

preconditions(especiallyonesthecalleedocumentsthatitwill

notcheck,suchasvector::operator[]whichdoesnot

promisetorange-checkitsargument).Becausethecalled

functioncannotrelyoncallerstobewell-behaved,however,the

calledfunctionoughtstilltovalidateitspreconditionsandto

reportviolationsbyemittinganerroror,ifthefunctionis

internalto(onlycallablefromwithin)themodule,sothatany

preconditionviolationisbydefinitionanerrorinthemodule's

programming,byasserting(seeItem68).Thisisdefensive

programming.

Awordofcautionaboutspecifyingafunction'spreconditions:A

conditionshouldbeapreconditionofafunctionfifandonlyif

itisreasonabletoexpectallcallerstocheckandverifythe

condition'svaliditybeforecallingf.Forexample,itiswrongfor

afunctiontostateapreconditionthatcanonlybecheckedby

doingsomeofthefunction'sownsubstantialwork,orby

accessingprivateinformation;thatworkshouldstayinthe

functionandnotbeduplicatedinthecaller.



Forexample,afunctionthattakesastringcontainingafile

namewouldnotnormallymakethefile'sexistencea

precondition,becausecallerscannotreliablyguaranteethatthe

fileexistswithouttakingalockonthefile(iftheyonlycheckfor

thefile'sexistencewithoutalock,anotheruserorprocesscould

deleteorrenamethefilebetweenthecaller'scheckandthe

callee'sattempttoopen).Onecorrectwaytomakethefile's

existenceapreconditionistorequirethecallertoopenthefile

andmakethefunction'sparameteranifstreamorequivalent

(whichisalsosafer,becauseitworksatahigherlevelof

abstraction)insteadofpassingabaldfilenameasaraw

string.Manypreconditionscanthusbereplacedbystronger

typing,whichturnsrun-timeerrorsintocompile-timeerrors

(seeItem14).



Examples

Example1:std::string::insert(preconditionerror).When

tryingtoinsertanewcharacterintoastringataspecific

positionpos,acallershouldcheckforinvalidvaluesofposthat

wouldviolateadocumentedparameterrequirement;for

example,pos>size().Theinsertfunctioncan'tperformits

worksuccessfullyifitdoesn'thaveavalidstartingpoint.

Example2:std::string::append(postconditionerror).When

appendingacharactertoastring,failuretoallocateanew

bufferiftheexistingoneisfullpreventstheoperationfrom

performingitsdocumentedfunctionandachievingits

documentedpostconditions,andisthereforeanerror.

Example3:Inabilitytoproduceareturnvalue(postcondition

error).Foravalue-returningfunction,producingavalidreturn

objectisapostcondition.Ifthereturnvaluecan'tbecorrectly

created(e.g.,ifthefunctionreturnsadouble,butthereexists

nodoublevaluewiththemathematicalpropertiesrequestedof

aresult),thatisanerror.

Example4:std::string::find_first_of(notanerrorinthe

contextofstring).Whensearchingforacharacterinastring,

failuretofindthecharacterisalegitimateoutcomeandnotan

error.Atleast,itisnotanerrorasfarthegeneral-purpose

stringclassisconcerned;iftheownerofthegivenstring

assumedthecharacterwouldbepresentanditsabsenceisthus

anerroraccordingtoahigher-levelinvariant,thathigher-level

callingcodewouldthenappropriatelyreportanerrorwith

respecttoitsinvariant.

Example5:Differenterrorconditionsinthesamefunction.In

spiteoftheincreasedreliabilityofdisksnowadays,writingto

diskhastraditionallyremainedsubjecttoexpectederrors.If



youdesignaFileclass,inthesamefunctionFile::Write(

constchar*buffer,size_tsize),whichrequiresthat

bufferisnon-nullandthatthefilebeopenedforwriting,you

mightdecidetodothefollowing:

IfbufferisNULL:Reportanerrorontheprecondition

violation.

IftheFileisread-only:Reportanerrorontheprecondition

violation.

Ifthewritedoesnotsucceed:Reportanerroronthe

postconditionviolation,becausethefunctioncannotdothe

workitpromisestodo.

Example6:Differentstatusforthesamecondition.Thesame

conditioncanbeavalidpreconditionforonefunctionandnot

foranother;thechoicedependsonthefunction'sauthor,whois

specifyinghisinterface'ssemantics.Inparticular,std::vector

providestwowaystoperformindexedaccess:operator[],

whichisnotbounds-checked,andat,whichis.Bothrequirea

preconditionthattheargumentisnotoutofrange.Because

operator[]isnotrequiredtovalidateitsargumentortobe

safetocallwithaninvalidargument,itmustdocumentthatthe

callerhassoleresponsibilityforensuringthattheargumentis

inthevalidrange;thisfunctionisinherentlylesssafe.Onthe

otherhand,atisdocumentedtobehavesafelyeveninthe

presenceofaninvalidargument,andtoreportanerror(by

throwingstd::out_of_range)iftheargumentisfoundtobe

outofrange.



References

[Abrahams01b][Meyer00][Stroustrup00]Đ8.3.3,Đ14.1,

Đ14.5[Sutter04b]



71.Designandwriteerror-safecode

Summary

Discussion

Examples

References



Summary

Promise,butdon'tpunish:Ineachfunction,givethestrongest

safetyguaranteethatwon'tpenalizecallerswhodon'tneedit.

Alwaysgiveatleastthebasicguarantee.

Ensurethaterrorsalwaysleaveyourprograminavalidstate.

Thisisthebasicguarantee.Bewareofinvariant-destroying

errors(includingbutnotlimitedtoleaks),whicharejustplain

bugs.

Prefertoadditionallyguaranteethatthefinalstateiseitherthe

originalstate(iftherewasanerrortheoperationwasrolled

back)ortheintendedtargetstate(iftherewasnoerrorthe

operationwascommitted).Thisisthestrongguarantee.

Prefertoadditionallyguaranteethattheoperationcanneverfail

atall.Althoughthisisnotpossibleformostfunctions,itis

requiredforfunctionslikedestructorsanddeallocation

functions.Thisistheno-failguarantee.



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

Chapter 70.  Distinguish between errors and non-errors

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

×