You are on page 1of 24
Architecture ‘Systems Building Objects and Clas: | | Relationships | | C++ for C Programmers “Architecture 2 Name Clashes 3 ‘Using Namespaces S Exception Handling 6 ‘The Standard Exception Eirarchy 7 “Throwing and Catching Exceptions 8 ‘Catching Different Exceptions 9 ‘Header Files 10 ‘lmplementation Files LL ‘Multiple clusion 12 ‘Header Fle Guards 13, “Writing Common Header Files 14 ‘Calling € from C4 15 Calling C+ from C16 Customised Memory Allocation 17 *Move Customised Memory Allocation 18 «Smart Pointers 19 +4 Reference Counted Smart Pointer 20 Summary 21 Clase Recommendations ‘System Recommendations 23 © QA Grow Lid (L3-090400019 (8) Pa Architecture + Objectives ~ Tobe aware o ho features avaliable for periioning a system logically, Dhyicaly and in terme of Behaviour + Contents = Namespaces = Exception handing = Header and source to = Cand Cr+ iteroperabity ~ Customised memory allocation = Smart points = Recommendations + Summary “There area number of language and library feaares that soppon the building of sealable, industeial stent programs. This chapter gives an overview of some of these features, & ‘couple of whicl ~ such as namespaces ~ are relatively new tothe language. One of C++s {greatest strength (and, itis often said, one ofits greatest weaknesses) is its C compatibility Cand C++ interoperability is looked at, hore are also language features to suppost ‘exception handling and optimised memory allocation, Following the summary ae slides that go into more detail on each ofthese subjects. Aso ‘cavered i the concept of smart pointers which representa programming solution to certain ‘memory management issues, Although source and header files are not srcily speaking a part ofthe language, they are the physical representation of u program, Understanding how to manage them ean have a positive impact on the development process. Finally, a number of programming recommendstions are presented. — (© 0A Group Lid (L3-990400019 3) - Page 202 Atchison Name Clashes + What if the same name is used for two difforont types? Consider using two aies GUILID and DBL. oun ati ine sive oamecanne {ns Je fs poten cable f [Name clashes i. the use ofthe same nume for different classes, ar almost a cetainry In large projects or when mixing many libraries, ‘These will use problems a compile time as certain source files wil fail to compile: clas cannot be redefined. ‘The two libraries Shown inthe cade above shove such a case: GUILib is a GUT library that offers & butcon class and a table class: DBLib is a database interfacing library with a Login class and als offers a Cable class, Clearly we cannot have to table classes inthe same program that do different things! Attempring to include them both in te same file will cause a ‘compilation error when the second s encountered, [Even if this were not the cave, use of classes would not automatically be obvious from the ‘context — perhaps possible forthe human reader. but certainly not the compile: & ‘Spreadsheet fs more ike to be a graphical table than a relational able ina database, and vice versa for information on employees. ‘And even if duplicate names are not used inthe same source file, the Fnker will til fail 16 ‘resolve unique references, Two object files containing definitions for functions with the same name vill cause a multiple syinbol definition otro. (Clearly some kind of scuctured solution is needed to resolve these issucs (© QA Geo Ld, 1 3.980400019 1) -Paze 3 of 3 Namespaces + Possible solutions include... Renaming ane or mre of tne sees “Aways using prefix convention... Gul 12/6, ob tble = Using nated type + Many of these solutions are retrospective, short term or cumbersome and are still open to problems + & namespace allows definitions to be placed in a separate named scope ‘cu BL euin anaepace sul ? Unlike clas the same namespace may be defined in many fle, soa library is open to (Cats namespace is comparable to the package or named module of other langunges, (BQ Group Lt, OMODDID 4) Page 4a 22 areitetre Using Namespaces Sep guinnton hielate! ais ees Wnclass .bop> gels sbucton ok Berioria vases Gulsstable sprendahect, Goiiesbie’ cepievecer ‘pelvebetbow chi Sesdogin cable Beanie ‘There are many ways 1 acoess he contents ofa nameepace: + Explicit qvatiication uses the namespace name, the scope resolution operator and the identifier for each use ofthe identifier. + A.using dectaration export & single name for use. The identifier may then be used on its ‘own, withthe compiler automatically resolving cto the one named inthe using declaration, + Ausing direcrive opens the whole namespace for use, so that all idemtifirs will b> accessible. Any conflicts with ther using directives must be tesolved by using one of the ther two methods. + Anamespace alias can be used to make names shorter, getting around the problem that vo libraries may have dhe same name: namespace long_library_name class feature (...}; } Aaneapace Zin = long_librazy_nane; feature creature; (© OA Group Lu, 3. 990400019) -Page Sof 23 Exception Handling + Traditional error handling techniques include ~ Returning vse from a funetion to incest successor fire tanore the ror = Log he eto, but ethers ignors it Put an objet into some hind of invalid sat hat canbe tested ~ boring te program + In. C++ an exception can be thrown ~ An exception is represented by an object ~ Throwing an exception tansers contol The unotion cl stacks unsound unl Randle cape of handing the exception objects type is founs For the majority of programmers, ther least Favourite chore is handling exceptions within « program! The number of ways something ean g0 wrong seems fo outmumber the ways itn go Fight, resulting in exception cade that seems to dvaf de core program logic (ne of the traditional approaches to signalling crtoes, especially in. isto return some kind of status value rom a function. There are o umber of problems with this + A series of such checks can lead to cascading if #1s= i£ cade thal can be hard o read and maintain, + Constructors do not havea retuea value for signalling any construction problems + Overloaded operators do nos havea spars return value for exceptions, + Return values are to easy to ignore An alternative technique is to have an object know of whether or not i is in a good or bad Sate. The caller can then explicitly sk itafler every operation. The problem with this is that although i can handle constructor problems again i ean clearly lea to ehamsy code, Tt also Feqires extra members for manipulating and representing the error, making the classless cohesive boring the program is an absolute Inst resort, but not a very good one. 1e3s up tothe aller of ‘component to determine sshat the failure policy shouldbe, and forthe called component to Metect any fuluze. Ifthe called component lakes it upon itself to also handle the enor in & way ‘hat might disrupt the program it can lead to design problems. The C+ solution is 10 repeesent exceptions as objets. As objects hey can be self describing, ‘whereus something like a simple integer valle ~ a5 used in other languages —is not very informative as it says nothing about the details ofan exception. The next feature of C's exception handling is that there is a separate path of eonrol for exceptions than for normal fnetion remms, Exceptions can be caught by defining a handler but there is otherwise no need to detect an exception in a fimetion solely o return ito that function’ calle so tt it ean fo the same — you only eaich exceptions yon are iteested in (© 0A Group Lad, L-99D100019 (8) - Page oF 23 The Standard Exception Hierarchy pect ere nee “The standard exception classes form a hierarchy that is used by the standard library for ‘Signalling errors, Bu may also be used in your code tothe same. 1+ exception isthe hase class for exceptions, "The what member function is used 9 sey a sting with dts ofthe excoption. 0 Teghe Sear i the be clas for caceptions logic, sich asa violated fonction precondition. + donain error ie used for reporting general domain eors, suet as negative values where ony postive values ave pormited. + Savadlid Srgumont is used for reporting genera invalid arguments, such as nul inter. + Tength_exros is used for attemps to resize containers heyond ther maximum possible represent a full i the program's ‘= GHE_of_xange isuse for reporting other arguments tha are outside of the permitted «Punt ie_evvor isthe has clas for general eros in program execution. + range efor fused to report errors arising fom values exceoding thet permed ‘ange diving ibe execution of fanlion + Sueeeou! efor iets foreporngathmetic vero cg, a mumere ale exceeding an upper + Ghaertl ow Brrr is used for reporting arithmetic underflow, i. a resuing val that 4 oo sal oe represented + Bad al Toc isthe excepion drown when an aitemp\ o allocate an (aise. when a program suffers memory exhaustion. bjeet using new Although objects of any type may be thrown — not just those within he hierarchy shown above — its sensible to use classes already defined in the standard exception hierarchy. If ‘now kind of exception is needed, a class for it can be detived from an existing clas, © Q& Gop Lu, L3-990800019 4) -Page Tol 33 Architecture Throwing and Catching Exceptions + Exceptions keep error detection separate from error — recovery = Sigalied using throw — Cavan using caton ater a ry block. S {ees tinct ae tte _ t | 6 nde aa itt Ea 1 Tene + co] SR tamn mean mar {A throw expression causes the low of control to immediately lee the xy block, and ‘continue unvining the function call sac nel an appropriate catch handler is found. An — ‘appropriate 2a cs handle wil be able to match its argument with the typeof the abject. thrown. Within cae handler the caught object maybe eferred to asa Local variable, whose name is declared in the cat-ch hander ike a funtion argument Inthe example abore the cat.ch handler catches exceptions of ype out_ot_range throwin by sein’ subscript operator In thiscase the ame caught is used to access the caught exezption within the Randle. The scope ofthe exception variable, caus sunt the end of de block of ts deelaing catch handler. Standard exceptions oer « member function what tat retusa desorption ofthe exception town. Inthe case above, auch what ¢) will tum the string "bad Sine" An allemative way ol sniting the eho expression Uses a femporay’ unnamed _ abject ofiype out oF range, as opposed to the declared Out object in the code above ghar & string: soperator(] (size_t index) Af (index >= eize()! throw out_of_range("bad index"); } 8A Gro Lid (99000019 Page oF 2S ascteoe Catching Different Exceptions Where ae te following excepuions caught? te i OT ator * pam » na wiecon; <— [ase] rate ee gee eee, throw atring(tne meceager);~<[Twoneaame —] . i 2 _ Gatch (bad attoe «ye Sagres : sn cere << Nour of manory* 2c coats] [Gees amy cers sh (exception @ caught ————-—} dom oer Gerr file names; le [Ensuring that the heuder files for List and se-ing is automaticaly included when the header for is included simplifies maintenance and malkes the class easier to use: just include its header! BA Grp Lid, L5-990400019 4} - Page 10023 implementation Files + Each header file should have a corresponding ~ Provides definitions cf the features detared inthe header ~ Includes other herders a8 required i pat ete tena erationees 4 Bin “4 . gona | ttn eet! i i hod Cah coecie RENE {oa Se. Potisiromsbisiy [Paonia te i oe We adopt the convention that header files end in -fapp and implementation files end in ‘ep. There are other conventions: +h for header file, although this gets confused with C files that use the same convention; sivocand ox; + sbhand .ce} Hand .C. although only on case sensitive file systems as otherwise these loo: ike C fies, Itis considered easier to manage the header and implementation file together if they have the same base name and matched sulfices, ie. -APP and . cpp rather than and - and file history, bpp» headers has done nothing wrong: they need to use the group ‘and £3]e_higt ory classes and, on the assumption thatthe headers ae self contained, hve simply included the headers foreach clas. The programmer should not be expected to knows about the dependency on 71st as itis merely an implementation detail, [tis used puivately within each clas, and so is not apart ofthe public interface the programmer relies © QA Group Ls (L3.990100019 4) Page 12023 Achitceme Header File Guards + Possible solution: = Let the usor got it our? ~iskeheeers safe fr multiple intusiont + The pre-processor supports conditional compilation “= Hosder inclusion guards shouldbe used forehand fies - pusndes g& uzez ancomen ge SLT Sitti iateine Shier siase ies 7" i h » (Ein iid In any large project. mulliple inclusion is inevitable, How should we dea with it? A paticulaly short sited soluon sto le the Ble user sox the resuling mess out ~ for {bvious reson ths solution fan umessonsble nd unpopular onet One of the praciples for header ie design outlined cartier to ensure tt header fils are fll sell contned and standalone. ‘Thy shoul encapauate their dependencies and manage thei O81 contents ‘The preprocessor provides a solution in the form of conditional compilation diteetives. The #EEnGeE directive wil ifthe symbol it depends om has not been defines (not deine) include the tet from the following lineup unl closing bends, Tr the symbol as lkeady beon defined that text will nx be neTuded Inthe example above he ist time that <1 . App» i included ina source fie, he List_t8ciUDED s)mbol will nc have been defined and so the header bods. what les betwen ihe 44 2de2 andthe Heaaif is cluded. The fee f sn ditectve Row induces the LEST INCLUDED mar, The next ime dhe Hear bled i he source file the condition will esaluate false the macro hasbeen defined, and the text ill ot benched. Thecefore ao clash and multiple inclusion problenss salve. ‘There is no fixed convention for bow the macro must be mmed; but one vay to ens Ut ital be unique serss a projec for it ose te name of the header ass bass LIST INCLUDED has been used hee, but other conventions inluds 2S PE, LEST_HDR and LEST_ It's posta tha the Maio uae sia upper ease so Dat it does notunterfere with your Gedinary ideaiiers, which donot use all upper ease _ (Other clevant propracessordcctives for conditional compilation include ‘© #12deF for checking that & macro has alkeady been defines + #5 for testing genctl conditions; — # elise for providing an alternative to any ofthe i forms © HeLiE for providinga kind of else if for #4 © QA Group Ld. (L3-990400019 A) Page 130625 Writing Gommon Header Files * The __ cplusplus macro is defined when compiling C++ ~ "na ory eee Eitiecttocnen ttre ores itary] ct ea ~ ‘, oo ewe ane a : crpedat rerect date t ie Says memes yaar alee aa aya fe evaree today's 3406 4/ Iti possible ro write headers that can be shared between C and Ca. Essentially Clean Cis the convention that should e alopted when writing such code, Here area few fearures to swatch out fore +A sexuct in Cdocs not create a new type withthe tag name, so typedef must be used, ‘There are no classes in C, and so al dat structures mus! be etrwces oF forward declared nly. + C does not support references, so pointers must be used. + An empty argument list in C oust he indicated with vata, whichis otherwise discouraged ince, _ + C docs not support overloxding. ‘There are no templates in C. + Chas no namespaces + Be careful about using / / comments as these are not yet standard in C, so. /* */ is, preferred. “The preprocessor symbol__eplusp_us is predefined hy C++ compilers during ‘compilation. This can be used to selectively use certain language features depending on ‘what Langoage is being compiled, similar technique can be used with Embedded C++, proper subset of C++ defined for use in embedded systems Thvtp: //w2v.caravan-net /ec2plus), which defines enbeddedcplusplus ‘during compilation, © QA Group Ld (L3-99400019 8) = Page M025 - Calling C from C++ ‘+ Recompile existing C source with a C++ compiler = Source code must be available Included the source fos In th projot = The € must be Cisan C Link existing object code into a C++ program Must know prototypes or have header files avatabio — Linkage specication engures tht core! caling convention used fume iameimoge exter #6" void log.errortoonst cher 4 ‘paar anndn onscreen Z Lap spect cane ‘ait insane Saga bocreyese ‘There is a lage body of functional C code in existence that would be unwise 19 discard in a move WOO and CH. C++ classes can be used to provide & crapper Fo C APIS ‘The frst approach to reuse wo include the C code as part ofthe project and compile it with 2 Cet compiler. ‘The source code must clearly be available and well written, conforming to ‘common Subser of C and C++ sometimes known as Clean C (discussed in C: A Reference ‘Manual (Harbison & Steele, duh edition, Prentice Hall. ISBN 0-13-326224-3)), This subset ‘can be compiled as both C and C1+ with the sae semanties, Nave thatC is wot a stict Subset of Cr+, but the majority of well written C code will compule cleanly as C+. [Existing C cade that has aveady been compiled aud for which the abject files are available «an be linked into a C+ application, However, between Cand Cir+ many systems differ in their calling conventions: call stack management order aud alignment of arguments and results on the stack; andthe link name 1o which the source idebifler resolves ‘A-common naming convention for C link names is that they axe pefixed with an underscore, ee. void log_error (const char *); ‘sapped othe symbel_2oq_exxox in the objet file. C++ hus moe sophisticated name rag, cae aca ont ick me iso vero smpiomented troup the ined pe sae kage supped be ‘mismahed protelpe an dfn wll eau ink eur raner an surpetsing Deu rune. There are diferent mare malin conventions the stateny decribed in he AEM Oraouted Cr Roerence Manual would have sien Low afvor FRCe had the faction above been coupled as C+. ‘To get aroun these diferent alling conventions linkgzespetearo cate to got acces in Cnt tothe funtion compiled as € we would need to be uso. Tn his extern "0" void log error{ecnat char + For ystems that support them, code using othe language calling conventions can be Sccested using nsitelhi eg. oxtery "Fortran® crewtomn. "Peaca!” (note that Smo compilers ad Keywords such ss foxtzan and pascal to achiove tis, but these ato noo-standard language eateusions), By default the linkage is extecn "C++" © QA Group Lt (L3-9N4O19 3) = Page IS 2 roi Calling'C++ irom C + Functions can be written in C++ that can be called in C ~ Compiled as C++ but will ave aC calling convention — Linkage specication determines calling convention and not the compilation tanguage plo sane estes VALE/HAM pola tine, S005 | Compton Ca any ca seid ploc_aatieoler | Sittetagne Soning somenton + Poin tor see cece Se eigna, pereco wd aL lak eset 9 point bth point ~ aww yoitsiay $y Pletare.cda(aaw point) 2 itis possible that where € aplication developments stil supported ates are developed in Cts, The C code ceatly cannot deal m concepts nich classes and templates, ti Should be able weal fictions C= designed forthe purpose. These Fnetions cam zt as Swappers presenting a Ck exterior bt interelly manipulating a2 00 famework © Trelbar slop nkag pelo ano he callecin Cea spy psny exten "ess forthe rosatype However itis posible to avea C+ funtion compile using another calling convention. Using th linkage specie inthis nay doesnot change the langage of ompation, imply the eallng convention, For example, nthe code show the Cele might expect oell he 264" potne funtion aaa point whereas staight Co compilation might uve 2edcpoint. Fi, Comping the C++ funtion with extern. "c* provides the Teauied compatible Depending on the specifi system ther languages can be sipported inthis way {© QA Group Lu. L3-990400019 4) Page 16 of 25 Customised Memory Allocation + new and delete expressions use allocation operators = System brary provides detault versions + new and delete operators may be redefined. = On global or per cass oasis ea stecaton orto aes sci slcaton operatns = Bi 20-0) Beste ati [By default, «program will use the mew and deLete uperators provide by the system for ‘obtaining dynamically allocated memory, It is possible to peovide replacement versions of these operators: + For debugging purposes; “+ To choose a faster allocation strategy; ‘To choose a more space efficient strategy ‘The 95:20_¢ argument taken by new is he actual size in bytes of the type being allocated. ‘This is automatically substituted by the compiler at compile type, using the si zeot ‘operator, The new operator retuins a pointer to raw memory, ped is youd The ‘compiler will automatically provide ube cast vo the right type and, importantly, call pproptiate constructor. With the delete operator the compiler il automatically call the desaructor. if any. on an ebject before passing the pomter to raw memory Hack for recovery ‘The programmer may fine une the allocation strategy using the mechanism shown, I non-invasive technique as the source cade i the rest ofthe program remains te st ‘a0 modification is equited and allocation can he instrumented an] optimisd at wil Iris albo possible to customise the failed allocation srategy without redefining opexator nov by using the sndard sec_new_handler function. By default, bad_alioc is thrown ifthe memory cannot be allocated. Using set_new handler itis possible give the memory management system a Turetion o eal when allocation fails. ‘This could Conceivably end the program, log the event, throw a different kind of exception, lree up some memory, of whatever the programmer decides is an appropriate memory exhaustion policy. Cass new and delete operators are implicitly etatic within a class as they refer to the class and not to an object. The stat ic keyword is optional but not ten used. © QA Ghowp Lid (L3-990400019 8) - Page 17a 25 More Customised Memory Allocation + Other forms of new can be provided to. ~ Allocate objects in shred memory Map objects onto system structures = exhibit aterentfalurestratgios + These forms of new take one or more arguments = They do not replace the ordinary new and must be eae explicitly phe S Wlactsow) very lanzes ke teen { SSEE Se tre aenony" << andy 1 [Normally the programmer does not eure where the memory for new is obtained. The allocation strategy ean he controlled forall objects by replacing the global neve and Gelete operatrs, or oma per class bass, kis also possible to provide versions of nes, known as placement nets, that take extra arguments, These exira arguments can be uscd (a say where in memory an object should be allocated, ar use another objet to specify the location — such asin memory shared between processes —or to eke a dummy argument that indicates a version of new that may provide 2 differen failure stutegy — in the ease of ne (nothrow) 2 failed allocation will result ina null pointer rather than «thrown exception. Inthe oxample above, the declaration forthe shaved memory version of new might look Tike: void * operator new(size_t size, shared memory & where); Its assumed that the shazed_ewory class encapsulates all the low level memary ‘mapping and manipulation, and is probably buileoa aC API. For the no thrave case, it wot Look lke: etxuct nothrow_t {hr extern const ndthrow_t nothrow: void + operator new(aize_t eize, const nothrow_t &); Here the notrow_€ type isan empty type, and notheow is a dummy variable used for the overloading, ‘The placement forms of ew exist alongside the ordinary form and may be provided at class cr global scope. In ellec there is no programmer usable form of placement dete. A Grow Lit 90490019 Page L028 Architecture Smart Pointers + Classes can be designed to behave like pointers ~ They detogatoto real objects but provide adtinalInemigence in tmethod staccess or contol — Operator overloading allows them fo Be used ke ordinary pointers ~ Templates can he used to make smart pointere genet rather than type specie + There are many different kinds of smart pointer ~ Checking pointers can automatically check against nul pointer usage ~ Reference counted pointers can automaticaly manage deletion of an boject wnenitia no ionger being eee ~The standard suo. pir template class canbe used to ensure that local “locaton is excepiion rato An object in database ean be loaded and manipulted automatioally ‘on demand by & smart pointer designed to do 50 ‘An object can be used to stand infor another ojeet. Such a proxy ar surrogate object Aslegates operations to ts target. Tn C+ the most common form of proxy isthe stuart Pointer. Inthis idiom an abject looks and behaves in many ways like a pointer, eg. through Dverloading it supports the dereference operators, * and -> A raw pointer knows only about raw memory and is potentially unsafe. A smact pointer can bbe made o act mote intelligently on behalf ots targeted object, This may involve smarter ‘memory manipulation and checking. dynamically loading an object on demand ftom 2 database, or delegating «call o an object across & network. An iterator is an example of a ‘tmat poner in tari encapsulates knowledge of container aocoss and ravers Smart pointers can make systoms more robust and more convenient to program, © 28 Group Lis L3-99M00019 8) Page 19 U2 Artie A Reference Counted Pointer ‘Goameed per woperator=(soust counted pte 8s ‘The counted _per class showin above eliminates the need for programmers to manually delete a object, The underlying principle is for the counted _ptr to delete the target Dbject when there are no more pointers (counted_ptr. tobe precise} w it. This is schieved using a reference count per object. When counted_pt= objects are copied, assigned or go out of scope the reference count is increased or Joercased accordingly. When the count draps to zero there are no more pointers to the object and so itcan be automatically deleted. ° ‘As containers are value based the most effective way to ge comtainers to hokd pointers and ‘manage their contents isto uss something like counted pry. ‘The counted_per class is nor part ofthe ISO C+ standard! lis however adefacio ‘andard, Aw implementation of Counced_ptr can be found in ga: etal ib+-+ inside the Ble qa/memozy nop © QA Growp Lid (3-99040019 4) = Page 20025 Summary + Namespaces ~Rogee mame clashes Ares mann of labeling systema oc pat ofa yates + Exceptions may be managed with try, throw and cateh ~Brige the gp betwen ear detection andere handing + Cand C++ can interoperate ~ Legacy € code ean be called from Cos + The new and delete operators = Customisable in orme of performance, + C++ is only a language ~ Batter systems can only be bull by understanding what Is required = Recommendations suppor the transation of design int lean code 9 and behaviour (C4 isa large and at times complex language that offers & number of feanies that support the programmer in building larg, eobust and elfciene systems (One issue that programmer’s must be aware of, especially those for whom portability is 2 ‘Concern, is that older compilers (those whose vendors baye not kept diem up co date) may hat support some features, These include templates, exception handling, and namespaces. However, the presence or ahsence of language features does not change C+ role asa programming language. On its own it wil nor salve system development problems Understandimg of requirements and 1 development cycle that suppors analysis and design as precursors to un implementation stage are crucial to successful development 6 QA Gow La (3-9) Page 2 Arcos ‘aasee snouts be const correct ‘lass interfaces should be minimal but Tunetionaly complete Ctassea snout be ogically complete, 0. 3 implies there shouts asa be Use operater overioading judiciously [Ensure hat classes are copy-sae: provide ‘copying behaviour yoursel asable oF ‘comment the dau 23 OK Ue public Ineritanes any where substitiabiiy is mesninghat ‘anale multipe innontonce win eare ‘public dostrctor in «base class should De ceciared vituat 2 Onainary member date shouldbe pr 10. Friends are generally there 10 Doevalded © 0A Group Ls, (LS. 9904000194}. Page 22025 Aeblecure Header fies shoul be self contained ‘and mute melusfon sate ‘Ensure that features iva head ate Iegialy related. ono! et header {es become ‘itton sinks" Excoptions should be exceptions! Optimisation should only be performed thon the naed is racogatsed, thus Inlnes should be used cautiously tat ai Use a consistent set of coding and syle © 0A Gaowp Lis 3 990400019) - Page 28 of 23

You might also like