Tải bản đầy đủ - 0 (trang)
Chapter 61.  Don't define entities with linkage in a header file

Chapter 61.  Don't define entities with linkage in a header file

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

Summary

Repetitioncausesbloat:Entitieswithlinkage,including

namespace-levelvariablesorfunctions,havememoryallocated

forthem.Definingsuchentitiesinheaderfilesresultsineither

link-timeerrorsormemorywaste.Putallentitieswithlinkagein

implementationfiles.



Discussion

WhilestartingtouseC++,wealllearnquitequicklythat

headerfileslike

//avoiddefiningentitieswithexternallinkageinaheader

intfudgeFactor;

stringhello("Hello,world!");

voidfoo(){/**/}



areliabletocauselink-timeerrorscomplainingofduplicate

symbolsassoonassuchaheaderisincludedbymorethanone

sourcefile.Thereasonissimple:Eachsourcefileactually

definesandallocatesspaceforfudgeFactorandhelloand

foo'sbody,andwhenthetimecomestoputitalltogether

(linking),thelinkerisfacedwithseveralsymbolsbearingthe

samenameandcompetingforvisibility.

Thesolutionissimpleputjustthedeclarationsintheheader:



externintfudgeFactor;

externstringhello;

voidfoo();//"extern"isoptionalwithfuncti



Theactualdefinitionsgoinasingleimplementationfile:

intfudgeFactor;

stringhello("Hello,world!");

voidfoo(){/**/}



Also,donotdefinitenamespace-levelstaticentitiesina

header.Forexample:

//avoiddefiningentitieswithstaticlinkageinaheader

staticintfudgeFactor;

staticstringhello("Hello,world!");

staticvoidfoo(){/**/}



Suchmisuseofstaticismoredangerousthanjustdefining

globalentitiesintheheader.Withglobalentities,atleastthe

linkerisliabletopromptlyuncovertheduplication.Butstatic

dataandfunctionsarelegaltoduplicatebecausethecompiler

recognizesthatyouareaskingforaprivatecopyineachsource

file.So,ifyoudefinestaticdataandstaticfunctionsinaheader

andincludethatheaderin50files,thebodiesofthefunctions

andthespaceforthedatawillbeduplicated50timesinthe

finalexecutablecode(exceptinthepresenceofsomemodern

linkersthatmergetogetheridenticalfunctionbodiesandconst

datawhensuchmergingissafe).Needlesstosay,globaldata

(suchasthestaticfudgeFactor)isnotreallyglobalbecause

eachsourcefileendsupmanipulatingitsowncopy,

independentofallothercopiesintheprogram.

Don'ttrytogetaroundthisby(ab)usingunnamednamespaces

inheaderfilesbecausetheeffectswouldbejustasunpleasant:

//inaheaderfile,thisisjustasbadasstatic

namespace{

intfudgeFactor;

stringhello("Hello,world!");

voidfoo(){/**/}

}



Exceptions

Thefollowingentitieswithexternallinkagecangoinheader

files:

Inlinefunctions:Thesehaveexternallinkage,butthelinker

isguaranteednottorejectmultiplecopies.Otherthanthat,

theybehaveexactlylikeregularfunctions.Inparticular,the

addressofaninlinefunctionisguaranteedtobeunique

throughoutaprogram.

Functiontemplates:Similartoinlinefunctions,

instantiationsbehavejustlikeregularfunctionsexceptthat

duplicatecopiesareacceptable(andhadbetterbe

identical).Ofcourse,agoodcompilationframework

eliminatestheunnecessarycopies.

Staticdatamembersofclasstemplates:Thesecanbe

particularlyroughonthelinker,butthat'snotyour

problemyoujustdefinetheminyourheaderfileandletyour

compilerandlinkerdealwithit.

Also,aglobaldatainitializationtechniqueknownas"Schwarz

counters"or"niftycounters"prescribesplantingstatic(or

unnamed-namespace)datainaheaderfile.JerrySchwarz

madethetechniquepopularbyusingittoinitializethestandard

I/Ostreamscin,cout,cerr,andclog.



References

[Dewhurst03]Đ55[Ellis90]Đ3.3[Stroustrup00]Đ9.2,

Đ9.4.1



62.Don'tallowexceptionstopropagate

acrossmoduleboundaries

Summary

Discussion

References



Summary

Don'tthrowstonesintoyourneighbor'sgarden:Thereisno

ubiquitousbinarystandardforC++exceptionhandling.Don't

allowexceptionstopropagatebetweentwopiecesofcode

unlessyoucontrolthecompilerandcompileroptionsusedto

buildbothsides;otherwise,themodulesmightnotsupport

compatibleimplementationsforexceptionpropagation.

Typically,thisboilsdownto:Don'tletexceptionspropagate

acrossmodule/subsystemboundaries.



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

Chapter 61.  Don't define entities with linkage in a header file

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

×