You are on page 1of 231

C++ Hackers Guide

Steve Oualline

C++ Hacker's Guide


by Steve Oualline

Page 1

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Copyright 2008, Steve Oualline !his "ork is licensed under the Creative Co##ons $icense "hich appears in %ppendi& ' (ou are )ree*

to Share + to copy, distri,ute, display, and per)or# the "ork to -e#i& + to #ake derivative "orks

.nder the )ollo"ing conditions*

%ttri,ution* (ou #ust attri,ute the "ork ,y identi)ying those portions o) the ,ook you use as /.sed ,y per#ission o) Steve Oualline 0http*11""" oualline co#2 under the the Creative Co##ons $icense 3 0!he attri,ution should not in any "ay that suggests that Steve Oualilne endorses you or your use o) the "ork2 'or any reuse or distri,ution, you #ust #ake clear to others the license ter#s o) this "ork !he ,est "ay to do this is "ith a link to the "e, page* http*11creativeco##ons org1licenses1,y14 01us1 %ny o) the a,ove conditions can ,e "aived i) you get per#ission )ro# Steve Oualline %part )ro# the re#i& rights granted under this license, nothing in this license i#pairs or restricts the author5s #oral rights

Page 2

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Table of Contents
-eal 6orld Hacks 7 Hack 1* 8ake Code 9isappear 10 Hack 2* $et So#eone :lse 6rite ;t 12 Hack 4* .se the const <ey"ord 're=uently 'or 8a&i#u# Protection 12 Hack >* !urn large para#eter lists into structures 1> Hack ?* 9e)ining @its 1A Hack A* .se @it )ields Care)ully 18 Hack B* 9ocu#enting ,it#apped varia,les 17 Hack 8* Creating a class "hich can not ,e copied 21 Hack 7* Creating Sel)Cregistering Classes 22 Hack 10* 9ecouple the ;nter)ace and the ;#ple#entation 2? Hack 11* $earning 'ro# !he $inu& <ernel $ist 'unctions 2B Hack 12* :li#inate Side :))ects 27 Hack 14* 9on5t Put %ssign#ent State#ents ;nside %ny Other State#ents 40 Hack 1>* .se const ;nstead o) Dde)ine 6hen Possi,le 41 Hack 1?* ;) (ou 8ust .se Dde)ine Put Parenthesis %round !he Ealue 42 Hack 1A* .se inline 'unctions ;nstead o) Para#eteriFed 8acros 6henever Possi,le 44 Hack 1B* ;) (ou 8ust .se Para#eteriFed 8acros Put Parenthesis %round !he argu#ents 4> Hack 18* 9on5t 6rite %#,iguous Code 4> Hack 17* 9on5t @e Clever 6ith the Precedence -ules 4? Hack 20* ;nclude (our O"n Header 'ile 4A Hack 21* SynchroniFe Header and Code 'ile Ga#es 4B Hack 22* Gever !rust .ser ;nput 48 Hack 24* 9on5t use gets >0 Hack 2>* 'lush 9e,ugging >1 Hack 2?* Protect array accesses "ith assert >2 Hack 2A* .se a !e#plate to Create Sa)e %rrays >? Hack 2B* 6hen 9oing Gothing, @e O,vious %,out ;t >A Hack 28* :nd :very Case "ith ,reak or 1H 'all !hrough H1 >B Hack 27* % Si#ple assert State#ents 'or ;#possi,le Conditions >B Hack 40* %l"ays Check )or !he ;#possi,le Cases ;n s"itches >8 Hack 41* Create Opa=ue !ypes 0Handles2 6hich can ,e Checked at Co#pile !i#e >7 Hack 42* .sing siFeo) 6hen Ieroing Out %rrays ?1 Hack 44* .se siFeo)0var2 ;nstead o) siFeo)0type2 in #e#set Calls ?1 Hack 4>* Iero Out Pointers to %void -euse ?4 Hack 4?* .se strncpy ;nstead o) strcpy !o %void @u))er Over)lo"s ?> Hack 4A* .se strncat instead o) strcat )or sa)ety ?? Page 4 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 4B* .se snprint) !o Create Strings ?A Hack 48* 9on5t 9esign in %rti)icial $i#its ?B Hack 47* %l"ays Check )or Sel) %ssign#ent ?8 Hack >0* .se Sentinels to Protect the ;ntegrity o) (our Classes A0 Hack >1* Solve 8e#ory Pro,le#s "ith valgrind A1 Hack >2* 'inding .ninitialiFed Earia,les A4 Hack 27* Ealgrind Pronunciation A? Hack >4* $ocating Pointer pro,le#s :lectric'ence A? Hack >>* 9ealing "ith Co#ple& 'unction and Pointer 9eclarations A? Hack >?* Create !e&t 'iles ;nstead o) @inary Ones 6henever 'easi,le AB Hack >A* .se 8agic Strings to ;denti)y 'ile !ypes A7 Hack >B* .se 8agic Gu#,ers )or @inary 'iles A7 Hack >8* %uto#atic @yte Ordering !hrough 8agic Gu#,ers B0 Hack >7* 6riting Porta,le @inary 'iles B1 Hack ?0* 8ake (ou @inary 'iles :&tensi,le B2 Hack ?1* .se #agic nu#,ers to protect ,inary )ile records B> Hack ?2* <no" 6hen to .se Je&it BA Hack ?4* 8ark te#porary de,ugging #essages "ith a special set o) characters B8 Hack ?>* .se the :ditor to %nalyFe $og Output B8 Hack ??* 'le&i,le $ogging B7 Hack ?A* !urn 9e,ugging On and O)) 6ith a Signal 81 Hack ?B* .se a Signal 'ile to !urn On and O)) 9e,ugging 82 Hack ?8* Starting the 9e,ugger %uto#atically .pon :rror 82 Hack ?7* 8aking assert 'ailures Start the 9e,ugger 88 Hack A0* Stopping the Progra# at the -ight Place 70 Hack A1* Creating Headings "ithin Co##ent 72 Hack A2* :#phasiFing "ords "ithin a paragraph 74 Hack A4* Putting 9ra"ings ;n Co##ents 74 Hack A>* Providing .ser 9ocu#entation 7> Hack A?* 9ocu#enting the %P; 7A Hack AA* .se the $inu& Cross -e)erence to Gavigate $arge Coding ProKects 77 Hack AB* .sing the PreCprocessor to Generate Ga#e $ists 104 Hack A8* Creating 6ord $ists %uto#atically 10> Hack A7* Preventing 9ou,le ;nclusion o) Header 'iles 10? Hack B0* :nclose 8ultiple $ine 8acros ;n do1"hile 10? Hack B1* .se Di) 0 to -e#ove Code 10B Hack B2* .se Di)nde) LLL to ;denti)y !e#porary Code 10B Hack B4* .se Di)de) on the 'unction Got on the 'unction Call to :li#inate :&cess Di)de)s 108 Hack B>* Create Code to Help :li#inate Di)de) State#ents 'ro# 'unction @odies 107 Hack B?* 9on5t .se any /6ell <no"n3 Speedups 6ithout Eeri)ication 112 Hack BA* .se g#ake CK to speed up co#pilation on dual processor #achines Page > Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

11? Hack BB* %void -eco#piling ,y .sing ccache 11B Hack B8* .sing ccache 6ithout Changing %ll (our 8ake)iles 118 Hack B7* 9istri,ute the 6orkload 6ith distcc 117 Hack 80* 9on5t Opti#iFe .nless (ou -eally Geed to 120 Hack 81* .se the Pro)iler to $ocate Places to Opti#iFe 120 Hack 82* %void the 'or#atted Output 'unctions 122 Hack 84* .se ++& ;nstead o) &++ @ecause ;t5s 'aster 124 Hack 8>* Opti#iFe ;1O ,y .sing the C ;1O %P; ;nstead o) the C++ One 12> Hack 8?* .se a $ocal Cache to %void -eco#puting the Sa#e -esult 12A Hack 8A* .se a Custo# ne"1delete to Speed 9yna#ic Storage %llocation 128 %ntiCHack 8B* Creating a Custo#iFed ne" 1 delete .nnecessarily 127 %ntiCHack 88* .sing shi)t to #ultiple or divide ,y po"ers o) 2 140 Hack 87* .se static inline ;nstead o) inline !o Save Space 141 Hack 70* .se dou,le ;nstead o) 'loat 'aster Operations 6hen (ou 9on5t Have % 'loating Point Processor 142 Hack 71* !ell the Co#piler to @reak the Standard and 'orce it !o !reat )loat as )loat 6hen 9oing %rith#etic 144 Hack 72* 'i&ed point arith#etic 14> Hack 74* Eeri)y Opti#iFed Code %gainst the .nopti#iFed Eersion 148 Case Study* Opti#iFing ,itsJtoJ,ytes 147 Hack 7>* 9esignated Structure ;nitialiFers 1>> Hack 7?* Checking print) style %rgu#ents $ists 1>? Hack 7A* Packing structures 1>A Hack 7B* Creating 'unctions 6ho5s -eturn Shouldn5t @e ;gnored 1>A Hack 78* Creating 'unctions 6hich Gever -eturn 1>B Hack 77* .sing the GCC Heap 8e#ory Checking 'unctions to $ocate :rrors 1>7 Hack 100* !racing 8e#ory .sage 1?0 Hack 101* Generating a @acktrace 1?2 %ntiCHack 102* .sing /Dde)ine e&tern3 )or Earia,le 9eclarations 1?A %ntiCHack 104* .se , 0co##a2 to Koin state#ents 1?8 %ntiCHack 10>* i) 0strc#p0a,,22 1?7 %ntiCHack 10?* i) 0ptr2 1A1 %ntiCHack 10A* !he /"hile 00ch M getch022 NM :O'23 Hack 1A1 %ntiCHack 10B* .sing Dde)ine to %ug#ent the C++ Synta& 1A4 %ntiCHack 108* .sing @:G;G and :G9 ;nstead o) O and P 1A4 %ntiCHack 107* Earia,le %rgu#ent $ists 1A> %ntiCHack 110* Opa=ue Handles 1AA %ntiCHack 111* 8icroso)t 0Hungarian2 Gotation 1AA Hack 112* %l"ays Eeri)y the Hard"are Speci)ication 1B0 Hack 114* .se Porta,le !ypes 6hich Speci)y :&actly Ho" 6ide (our ;ntegers %re 1B1 Hack 11>* Eeri)y Structure SiFes 1B2 Page ? Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 11?* Eeri)y O))sets 6hen 9e)ining the Hard"are ;nter)ace 1B> Hack 11A* Pack Structures !o :li#inate Hidden Padding 1B> Hack 11B* .nderstand 6hat the <ey"ord volatile 9oes and Ho" to .se ;t 1B? Hack 118* .nderstand 6hat the Opti#iFer Can 9o !o (ou 1BB Hack 117* ;n :#,edded Progra#s, !ry !o Handle :rrors 6ithout Stopping 180 Hack 120* 9etecting Starvation 182 Hack 121* !urning on Synta& Coloring 18? Hack 122* .sing Ei#5s internal #ake syste# 18? Hack 124* %uto#atically ;ndenting Code 188 Hack 12>* ;ndenting :&isting @locks o) Code 188 Hack 12?* .se tags to Gavigate the Code 170 Hack 12A* (ou Geed to 'ind the $ocation o) Procedure )or 6hich (ou Only <no" Part o) the Ga#e 17> Hack 12B* .se *vi#grep to Search )or Earia,les or 'unctions 17A Hack 128* Eie"ing the $ogic o) $arge 'unctions 17B Hack 127* Eie" $og)iles "ith Ei# 177 Hack 140* 'lipping a Earia,le @et"een 1 and 2 201 Hack 141* S"apping !"o Gu#,ers 6ithout a !e#porary 202 Hack 142* -eversing the 6ords ;n a String 6ithout a !e#porary 20> Hack 144* ;#ple#enting a 9ou,le $inked $ist "ith a Single Pointer 20A Hack 14>* %ccessing Shared 8e#ory 6ithout a $ock 20B Hack 14?* %ns"ering the O,Kect Oriented Challenge 207 %ppendi& %* Hacker Luotes Grace Hopper $inu& !orvals %ppendi& @* (ou <no" (ou5re a Hacker ;) %ppendi& C* Hacking Sins .sing the letters O, l, ; as varia,le na#es Got Sharing (our 6ork Go Co##ents ;ncOnsis!enc( 9uplicating Code 0Progra##ing ,y Cut and Paste2 %ppendi& 9* Open Source !ools 'or Hackers ctags Q 'unction ;nde&ing Syste# do&ygen 'la"'inder gcc Q !he GG. C and C++ co#piler suite l&r 218 Perl 0)or perldoc and related tools2 Q 9ocu#entation Syste# valgrind 0#e#ory checking tools2 Ei# 0Ei ;#proved2 Page A 211 211 212 21> 21A 21A 21A 21A 21A 21B 218 218 218 218 218 217 217 217

Copyright 2008, Steve Oualline

C++ Hackers Guide %ppendi& :* Sa)e 9esign Patterns %ppendi& '* Creative Co##ons $icense $icense Creative Co##ons Gotice

Steve Oualline 220 22? 22? 240

Page B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Preface
Originally ter# hacker #eant so#eone "ho did the i#possi,le "ith very little resources and #uch skill !he ,asic de)inition is /so#eone "ho #akes )ine )urniture "ith an a&e3 Hackers "ere the people "ho kne" the co#puter inside and out and "ho could per)or# cool, clever, and i#possi,le )eats "ith their co#puters Go" days the ter# has ,een corrupted to #ean so#eone "ho ,reaks into co#puters, ,ut in this ,ook "e use hacker in its original honora,le )or# 8y )irst introduction to true hackers "as "hen ; Koined the 8idnight Co#puter Clu, "hen ; "ent to college !his "asn5t an o))icial clu,, Kust a group o) people "ho hung out in the P9PC8 la, a)ter #idnight to progra# and discuss co#puters ; re#e#,er one )ello" "ho had taken R10 o) parts )ro# -adio Shack and created a little ,lack ,o& "hich he could use "ith an oscilloscope to align 9:C!ape drives 9:C at the ti#e needed a R4?,000 custo# ,uilt #achine to do the sa#e thing !here "ere also so#e people there "ho enKoyed progra##ing the P9PC8 to play #usic !his "as kind o) hard to do since the #achine didn5t have a sound card @ut so#eone discovered that i) you put a radio near the #achine the inter)erence could ,e heard on the speaker %)ter playing around "ith the syste# )or a "hile people discovered ho" to generate tones using the inter)erence and thus 8.S;CC8 progra##ing syste# "as ,orn So that the syste# didn5t have a sound card didn5t stop hackers )ro# getting sound out o) it !his illustrates one o) the attri,utes o) great hacks, doing the /i#possi,le3 "ith totally inade=uate resources 8y )irst real hack occurred "hen so#e )riends o) #ine "ere taking asse#,ly language !heir Ko, "as to "rite a )unction to do a #atri& #ultiply ; sho"ed the# ho" to use the P9PC105s a,ility to do dou,le indirect inde&ed addressing1 "hich cut do"n the a#ount o) "ork needed to access an ele#ent o) the #atri& )ro# one #ultiply per ele#ent to one #ultiply per #atri& !he pro)essor "ho taught the asse#,ly class )elt that the only reason you5d ever "ant to progra# in asse#,ly is )or speed, so he ti#ed the ho#e"ork and co#pared the results against his /opti#al3 solution :very once in a "hile he5d )ind a progra# that "as slightly )aster, ,ut he "as a good progra##er so people rarely ,eat hi#
1 !he only #achines ; kno" o) "ith this strange addressing #ode "ere the P9PC10 and P9PC20 !he closest you can co#e this hack on today5s #achines involves vectoriFing the #atri&

Page 8

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

:&cept "hen it ca#e to #y )riends5 #atri& #ultiply assign#ent !he slo"est ca#e in at ten ti#es )aster than his /opti#al3 solution !he )astest "as so )ast that it ,roke the ti#ing tools he "as using He had to ad#it it "as a neat hack 0%)ter seeing this very strange code, he did so#ething very unusual )or a pro)essor* he called #y )riends to the )ront o) the class, gave the# the chalk and had the# teach hi# 2 6hat #akes a good hackS ;t involves go over, around, or through the li#itations i#posed ,y the #achine, the co#piler, #anage#ent, security2 or any thing else !rue hackers develop tricks and techni=ues designed to overco#e the o,stacles in )ront o) the# and to i#prove the =uality o) the syste#s they "ork "ith !hese are the true hacks !his ,ook contains a collection o) hacks ,orn out o) over )orty years o) progra##ing e&perience Here you5ll )ind all sorts o) hacks to #ake your progra#s #ore relia,le, #ore reada,le, and easier to de,ug ;n the true hacker tradition, this is the result o) o,serving "hat "orks and ho" it "orks, i#proving the syste#, and then passing the in)or#ation on

Real World Hacks


; a# a real "orld progra##er so this ,ook deals "ith real "orld progra#s 'or e&a#ple, there is a ,it o) discussion on the care and )eeding o) C style strings 0char*2 !his has angered so#e o) the C++ purist "ho ,elieve that you should only use only C++ strings 0std::string2 in your progra#s !hat #ay ,e true, ,ut in the real "orld there are lots o) C++ progra#s "hich use C style strings %ny "orking hacker has to deal "ith the# ;dealis# is nice, ,ut ; "ork )or a living and this ,ook is ,ased on real "orld, "orking progra#s, not the ones you )ind in the ideal "orld So to all the real "orld hackers out there, ; dedicate this ,ook

2 !rue hackers only ,reak security to discover "eaknesses in the syste# or to #ake i#prove#ents that the current security policy doesn5t allo" the# to do !hey don5t ,reak into so they can steal, copy protected in)or#ation, or spy on other people

Page 7

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 1: General Programming Hacks


C++ is not a per)ect language %s such so#eti#es you #ust progra# around the li#its i#posed on you ,y the language ;n this chapter "e present so#e o) the si#ple, co##on hacks "hich you can use to #ake your progra#s si#pler and #ore reada,le

Hack 1: Make Code Disappear


The Problem: 6riting code takes ti#e and introduces risk The Hack: 9on5t "rite code %)ter all the code that you don5t "rite is the easiest to produce, de,ug, and #aintain % Fero line progra# is the only one you can ,e sure has no ,ugs % good hacker kno"s ho" to "rite good code %n e&cellent hacker )igures out ho" to not "rite code at all 6hen you are )aced "ith a pro,le#, sit do"n and think a,out it So#e large and co#ple& pro,le#s, are really Kust s#all, si#ple pro,le#s hidden ,y con)used users and a#,itious re=uire#ents (our Ko, is to )ind the s#all si#ple solution and to not "rite code to handle the large con)using one $et #e give you an e&a#ple* ; "as asked to "rite a license #anager "hich allo"ed users "ho had a license key to run the progra# !here "ere t"o types o) licenses, those that e&pired on a certain date and those that never e&pired Gor#ally so#eone "ould design the code "ith so#e e&tra logic to handle the t"o types o) licenses ; re"rote the re=uire#ents and dropped the re=uire#ent )or licenses that never e&pired ;nstead "e "ould give our evaluation custo#ers a license that e&pired in A0C70 days and give custo#ers "ho purchased the progra# a license that e&pired in 20484 !hus our t"o types o) licenses ,eca#e one %ll the code )or per#anent license disappeared and "as never "ritten ;n another case ; had to "rite a ne" reporting syste# )or a co#pany !heir e&isting syste# "as "ritten in a scripting language that "as Kust to slo" and li#ited %t the ti#e they had 4B types o) reports 6ith 4B pieces o) code to generate these 4B reports

4 !he .G;T time_t type runs out o) ,its in this year

Page 10

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

8y Ko, "as to translate these 4B pieces o) code )ro# one language to another ;nstead o) Kust doing "hat ; "as told, ; sat do"n and studied "hat "as ,eing done 6hen #y ,oss asked "hy ; "asn5t coding, ; told hi# that ; "as thinking, a step ; did not consider optional ;t turns out that ; "as a,le to distill the 4B di))erent reports into Kust 4 report types %ll 4B reports could ,e generated using these three types and so#e para#eters %s a result the a#ount o) code needed to do the "ork "as cut do"n ,y at least a )actor o) 10 -e#e#,er the code that you never "rite is the =uickest to produces and the #ost ,ug )ree code you5ll ever #ake Hacking so#ething out o) e&istence is one o) the highest )or#s o) hacking Producing Lines of Code ; "as once tasked "ith updating a large "e, ,ased reporting syste# "ritten in Perl %t this ti#e #anage#ent decided to #easure lines o) code "ritten to see ho" productive its progra##ers "ere @ecause o) the /design3 o) the Perl synta&, the di))erence ,et"een ,ad progra##ers and good one is a#pli)ied !he )irst "eek, ; cleaned up the o,vious ine))iciencies and re#oved a lot o) redundant and useless code 8y score )or that "eek "as a,out +1,B00 lines produced So the progra# got s#aller even though ; added lots o) co##ents and a couple o) ne" )eatures 'or ne&t )e" "eeks ; continued to reduce the siFe o) the progra# !he ,ig change ca#e "hen ; took out the old style, /call )unction, check )or error, pass error up the call change3 logic and replaced it "ith e&ception ,ased error handling> !hat change lost us ?,000 lines 8y #anager asked #e "hy they should ,e paying #e the ,ig ,ucks since #y Dlines produced 1 "eek "as negative ; told the# that that "as precisely "hy they "ere paying #e the ,ig ,ucks @ecause it takes a really e&cellent progra##er to produce ne" )eatures in negative lines o) code

> !he perl #odule :rror i#ple#ents e&ceptions

Page 11

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 2: Let Someone Else Write It


The Problem: 6riting code is slo" 6rite good code is slo"er, and even i) you "rite good code, you need to spend ti#e de,ugging it The Hack: @uild on the "ork that has proceeded you Ge&t to don5t do it at all, let so#eone else do it is the easiest "ay o) progra##ing !here are thousands o) tools, progra#s, and other so)t"are out there One o) these #ight do your Ko, )or you ;) not, it #ight al#ost do the Ko, so all you have to do is do"nload )i& it up a little and use it One good source )or Open Source so)t"are is http*11""" )resh#eat net ;t is a "e, ,ased data,ase containing a entry )or #ost so)t"are proKect Go" i) you do use Open Source so)t"are as a ,ase )or your "ork, you have an o,ligation to contri,ute ,ack to the co##unity any enhance#ents you5ve created !his lets other people use your "ork as a ,ase )or their progra#s ;t should ,e pointed out that so#e people "ho are not )a#iliar "ith ho" Open Source "orks are a little )rightened ,y it !hey tends to ,e ,usiness #en "ho can5t understand ho" so#eone "ould #ake #oney "riting open source code !he secret is that Open Source is not "ritten ,y people "ho "ant #oney ,ut ,y people "ho "ant so)t"are that "orks %nd i) you "ant a progra# that Kust "orks, one o) the easiest "ays o) /creating3 it is to use other peoples5 "ork as a starting point !hat5s the hacker spirit* (ou don5t Kust copy "hat so#eone else has done, you push the state o) the art )or"ard

Hack 3: Use the const 'rotection

e!"ord #re$%entl! #or Ma&im%m

The Problem: (ou pass a string 0char*2 into a )unction and the code gets con)used ,ecause so#eone accidentally #odi)ied the pointer The Hack: !ell the co#piler that the pointer is not to ,e changed !his hack #akes use o) one o) the #ore di))icult to understand concepts o) the C++ language, that o) const and pointers 6e5ll start "ith the declaration* const char* ptr_a;

Page 12

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he =uestion is /6hat does the const #odi)yS3 9oes it a))ect the pointer or does it a))ect the data pointed to ,y the pointerS ;n this case the const tells the co#piler that the character data is constant !he pointer itsel) can ,e reassigned const char* ptr_a; !hat #eans that "e can reassign the pointer* ptr_a = A New Value; @ut you can5t #odi)y the data pointed to ,y the pointer* *ptr_a = 'x'; // I !"A Go" let5s consider another declaration* char* const ptr_#; ;n this case the pointer is a))ected ,y the const !he data pointed to is not So "e can change the data ,eing pointed to* *ptr_# = 'x'; // egal !"A @ut "e can not change the pointer* ptr_# = A new string; // I %nd o) course there5s the o,vious declaration in "hich ,oth the pointer and the data are constant* const char* const ptr_c; Go" let5s go ,ack to our )unction call ;) "e are e&pecting constant data, then let5s speci)y it in the )unction para#eters* $oid displa%_string&const char* const the_string'; Go" any atte#pt to #odi)y the string "ill result in a co#pile ti#e error %nd co#pile ti#e errors are #uch easier to locate and )i& than run ti#e errors The const Memory Hack ;t5s not o,vious )ro# the synta& "here a const key"ord a))ects the pointer or the character @ut there is a si#ple #ne#onic trick that #ay help you re#e#,er "hich is "hich

Page 14

Copyright 2008, Steve Oualline

C++ Hackers Guide !he const #odi)ies the ele#ent it5s nearest 'or e&a#ple*

Steve Oualline

const char* ptr_s;


;n this case const is nearer to char than it is to *, so the data 0char2 is constant ;n the other case*

char* const ptr_t;


the const is nearer to the * than it is to the char, so the pointer is constant, not the data 0char2

Hack (: )%rn lar*e parameter lists into str%ct%res


The Problem: 'unctions that take a large nu#,er o) para#eters are di))icult to deal "ith Para#eters can easily get #i&ed up %lthough there5s no li#it on the nu#,er o) para#eter you can pass to a )unction, in practice #ore than a,out si& tend to #ake )unction calls di))icult to use Consider the )ollo"ing )unction call to dra" a rectangle* draw_rectangle& x() %() x*) %*) // +he corners o, the rectangle width) // -idth o, the line ,or the rectangle ./ /0_1 2!) // ine color ./ /0_3IN4) // 5ill color 6/ I7_5I ) // 5ill t%pe A1/V!_A // 6tac8ing order 9+i:es9) // 5ont ,or la#el (;) // 3oint si<e ,or la#el 96tart9 // a#el '; !his code is an accident "aiting to happen 'orget a para#eter and the code "on5t co#pile 6orse, reverse t"o para#eters and your code #ay co#pile ,ut dra" the "rong thing The Hack: .se a structure to pass a ,unch o) para#eters $et5s see ho" that "ould "ork )or our rectangle )unction

Page 1>

Copyright 2008, Steve Oualline

C++ Hackers Guide // 7e,ine how to draw the rectangle struct draw_para:s :%_draw_st%le; :%_rect=width = width; :%_rect=line_color = ./ /0_1 2!; :%_rect=,ill_color = ./ /0_3IN4; :%_rect=,ill = 6/ I7_5I ; :%_rect=stac8 = A1/V!_A ; :%_rect=la#el_,ont = 9+i:es9; :%_rect=la#el_si<e = (;; :%_rect=la#el = 96tart9; draw_rectangle&x() %() x*) %*) >:%_draw_st%le';

Steve Oualline

Go" instead o) passing para#eters ,y position they are passed ,y na#e !his #akes the code #ore relia,le 'or e&a#ple, you no longer have to re#e#,er i) the line color co#es )irst or the )ill color co#es )irst 6hen you "rite it as* :%_rect=line_color = ./ /0_1 2!; :%_rect=,ill_color = ./ /0_3IN4; it5s clear "hich is the line color and "hich is the )ill Hacking the Hack: !he draw_para:s structure can ,e used not only )or dra"ing a rectangle ,ut )or dra"ing other shapes as "ell 'or e&a#ple* draw_rectangle&x() %() x*) %*) >:%_rect'; draw_circle&x?) %?) radius) >:%_rect'; ;t is a good idea to #ake the de)ault value )or any para#eter Fero !hat "ay, you can set everything to the de)ault using the state#ent* :e:set&>:%_rect) '@;') si<eo,&:%_rect''; !he )rees you )ro# having to set values )or every ite# in the structure 'or e&a#ple, to dra" a red rectangle using the de)ault "idth, )ill, and la,el para#eters, use the )ollo"ing code* :e:set&>:%_rect) '@;') si<eo,&:%_rect''; :%_rect=line_color = ./ /0_0!7; draw_rectangle&x() %() x*) %*) >:%_rect'; ;) you are using C++, the draw_para:s structure can ,e #ade a class !he class can provide internal consistency checking to the user 0USetting the la,el to 5)oo5 "ith a point siFe o) 0 #akes no sense to #e U2

Page 1?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack +: De,inin* -its


The Problem: (ou need to de)ine a constant )or U,it ?U 're=uently progra##ers are re=uired to access various ,its )ro# a ,yte Here5s a diagra# )ro# a hard"are #anual )or a 9$! tape drive*

(ou need to de)ine constants to access the various ,its in the option ,yte 0@yte 22 One "ay o) doing this to de)ine a he&adeci#al constant )or each co#ponent // 1ad .ode const int /"_5 const int /"_5 const int /"_5 const int /"_5 A"_72 = ;xA;; A"_76 = ;xB;; A"_+67 = ;x*;; A"_!+. = ;x(;; // // // // 7isa#le update 7isa#le sa$e +arget sa$e disa#led !na#le thres= co:p=

!he pro,le# is that the relationship ,et"een 0&>0 and ,it A is not o,vious ;t5s easy to get the ,its con)used // "ood code const int /"_5 const int /"_5 const int /"_5 const int /"_5 A"_72 = ( CC D; A"_76 = ( CC E; A"_+67 = ( CC F; A"_!+. = ( CC B; // // // // 7isa#le update 7isa#le sa$e +arget sa$e disa#led !na#le thres= co:p=

Go" it5s easy to see that 0(CCB2 is ,it > Warning: 8ake sure you kno" "hich end is "hich ;n the previous e&a#ple ,it Fero is the least signi)icant ,it 0right#ost ,it2

Page 1A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut so#e people la,el ,it 0 as the #ost signi)icant ,it 0le)t#ost ,it2 'or e&a#ple the ;nternet Speci)ication -'C B71 de)ines the /!ype o) Service3 )ield as 0spelling errors in the original2*
Bits 0-2: Bit 3: Bits 4: Bits %: Bit (-): Precedence. 0 = Normal Delay, 1 = Low Delay. 0 = Normal T ro!" #!t, 1 = $i" T ro!" #!t. 0 = Normal &eli'ility, 1 = $i" &eli'ility. &eser*ed +or ,!t!re -se.

0 1 2 3 4 % ( ) .-----.-----.-----.-----.-----.-----.-----.-----. / / / / / / / / P&010D0N10 / D / T / & / 0 / 0 / / / / / / / / / / / / / / / .-----.-----.-----.-----.-----.-----.-----.-----.

VSpelling errors in the original W 6e can still use our shi)t hack to de)ine ,its in this "ay Only "e start "ith the constant 0&80 and shi)t to the right 'or e&a#ple* // "ood code // 7ela% ,lag const unsigned int I3+/6_ /-7! AG = ;xA; HH ?; // +hroughput ,lag const unsigned int I3+/6_+I0/2"I32+ = ;xA; HH B; // 0elia#ilit% ,lag const unsigned int I3+/6_0! IA1I I+G = ;xA; HH F; 6arning* 8ake sure that you use unsigned int instead o) [signed] int "hen de)ining the constants Signed integers "ill cause the sign ,it to ,e replicated in the data yielding une&pected results Trivia: !he )ollo"ing is the de)initions as de)ined in the $inu& standard header )ile /usr/include/netinet/ip.h: Jde,ine I3+/6_ /-7! AG Jde,ine I3+/6_+I0/2"I32+ Jde,ine I3+/6_0! IA1I I+G ;x(; ;x;A ;x;B

(ou #ay have noticed that they don5t use this hack 6ithout looking at the previous page can you tell "hich ,it is represented ,y I3+/6_ /-7! AGS

Page 1B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack .: Use -it ,ields Care,%ll!


The Problem: (ou "ant to use ,it )ields so that you don5t have to test, set, and clear ,its the hard "ay 'or e&a#ple* struct ti:esta:p K unsigned int ,lags:B; unsigned int o$er,low:B; L; The Hack: % good hacker treats ,it )ields "ith care !here are a nu#,er o) pro,le#s "ith their use !hese include* 1 Order is not guaranteed 2 Packing is not guaranteed 4 (ou really kno" "hat can and can5t ,e put in a )ield !his is especially true "hen dealing "ith a ,it)ield one ,it "ide as "e shall see ,elo" !he C++ standard #akes no guarantee "here the ,its o) ,it )ield "ill end up ;n the previous e&a#ple, the co#piler #ay* 1 %ssign the )ield ,lags to the high ,its and o$er,low to the lo" ,its 2 %ssign the )ield over)lo" to the high ,its and ,lags to the lo" ,its 4 ;gnore the ,it)ield speci)ication and assign o$er,low and ,lags to di))erent ,ytes !he $inu& operating syste#s assu#es that you are using the GCC co#piler "hich does pack #ultiple )ields into a single ,yte @ut the ordering o) these )ields depends on the endianness o) the #achine

Page 18

Copyright 2008, Steve Oualline

C++ Hackers Guide !his results in so#e strangeness in the header )iles* struct ti:esta:p K Ji, __1G+!_/07!0 == __ I++ !_!N7IAN unsigned int ,lags:B; unsigned int o$er,low:B; Jeli, __1G+!_/07!0 == __1I"_!N7IAN unsigned int o$er,low:B; unsigned int ,lags:B; Jelse J error 93lease ,ix C#its/endian=hH9 Jendi, L;

Steve Oualline

!here5s one other gotcha you have to ,e concerned a,out "ith ,it )ields !ake a look at the )ollo"ing code* struct ,lag_set K int #ig:(; int #igger:(; int #iggest:(; L; // === ,lag_set the_set; the_set=#ig = (; std::cout CC #ig ,lag is CC the_set=#ig CC std::endl; !he output o) this progra# is not /,ig )lag is 13 6hat is going onS !he pro,le# is that "e have a one ,it signed integer ;n a signed integer the )irst ,it is the sign ,it ;) the )irst ,it the nu#,er is negative So a single ,it signed nu#,er can only take t"o values, 0 and C1 So the state#ent* the_set=#ig = (; sets the sign ,it to 1 #aking the nu#,er negative, setting the )ield to C1

Hack /: Doc%mentin* 0itmapped 1aria0les


The Problem: @it#apped data is =uite co##on ,ut co#ple& and di))icult to use Such data declarations should really ,e co##ented, ,ut un)ortunately there5s no "ay )or a progra##er to dra" )igures or ta,les inside a progra# ;t is possi,le to docu#ent things using an e&ternal docu#ent, ,ut the pro,le# "ith e&ternal docu#ents is that they get out o) date easily or get lost Page 17 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;deally the docu#entation should ,e e#,edded in the progra# as co##ents %)ter all, it5s di))icult to loose X a progra# )ile Ho"ever, all the nice "ord processor dra"ing )unctions you5re used to having "hen you "rite a docu#ent are #issing "hen you are "riting a progra# ;nstead you have to get creative "ith the #ono spaced single )ont used )or "riting progra#s Here5s one e&a#ple "hich uses %SC;; art to dra" lines )ro# the ,its to their description* /* * /"_6! !.+ para:eters #%te * * MNNNNNNNNNN 72 &7isa#le 2pdate' * OMNNNNNNNNN 76 &7isa#le 6a$e' * OOMNNNNNNNN +67 &+arget 6a$e 7isa#le' * OOOMNNNNNNN !+. &!na#le +hreshold .o:pression' * OOOOMMNNNNN +P. &+hreshold Pet .riteria' * OOOOOOMNNNN 0s$d &0eser$ed' * OOOOOOOMNNN 3 & ist 3ara:eter' * DEFB?*(; */

!he other #ethod is to use the that they use in the -'C docu#ents Here5s a co##ent #ade )ro# an e&cerpt )ro# -'C B71* /* * 1its ;N*: 3recedence= * 1it ?: ; = Nor:al 7ela%) ( = ow 7ela%= * 1its B: ; = Nor:al +hroughput) ( = Iigh +hroughput= * 1its F: ; = Nor:al 0eli#ilit%) ( = Iigh 0eli#ilit%= * 1it END: 0eser$ed ,or 5uture 2se= * * ; ( * ? B F E D * MNNNNNMNNNNNMNNNNNMNNNNNMNNNNNMNNNNNMNNNNNMNNNNNM * O O O O O O O * O 30!.!7!N.! O 7 O + O 0 O ; O ; O * O O O O O O O * MNNNNNMNNNNNMNNNNNMNNNNNMNNNNNMNNNNNMNNNNNMNNNNNM */ VSpelling errors in the original W

Page 20

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Copying )ro# a standard like this has the added advantage o) )aith)ully reproducing the in)or#ation in the standard, thus producing good docu#entation %nd since all you did "as copy and past the a#ount o) "ork re=uired "as #inor !he only dra",ack to copy and paste is that any )la"s in the original, such as the spelling error a,ove are also reproduced

Hack 2: Creatin* a class "hich can not 0e copied


The Problem: (ou5ve created a co#ple& class ,ut don5t "ant to create a copy constructor or assign#ent operator )or the class @esides no,ody should ,e copying any instances o) this class any"ay One solution is to create a copy constructor "hich a,orts the progra# i) it5s called* // -or8s) #ut not opti:al class no_cop% K // === pu#lic: no_cop%&const no_cop%>' K std::cerr CC 9!00/0: no_cop%&no_cop%' called9 CC std::endl; a#ort&'; L L; !his "orks ,ut you5d rather detect the pro,le# at co#pile ti#e than run ti#e The Hack: 9eclare the copy constructor and assign#ent operator private class no_cop% K // === pri$ate: no_cop%&const no_cop%>'; no_cop%> operator = &no_cop%>'; L; Go" let5s see "hat happens "hen you try and use the copy constructor* no_cop% a_$ar; // +his will result in a co:pile error no_cop% #_$ar&a_$ar'; Page 21 Copyright 2008, Steve Oualline

C++ Hackers Guide !he result is the error #essage*


no2co#y.cc:%: error: 3no2co#y::no2co#y4const no2co#y567 is #ri*ate no2co#y.cc:10: error: wit in t is conte8t

Steve Oualline

Go" in actual practice your call to the copy constructor #ay not ,e so o,vious 6hat "ill pro,a,ly happen is that you5ll accidentally call the copy constructor through para#eter passing or so#e other hidden code @ut the nice thing is that no" "hen you do call it, you5ll discover the pro,le# at co#pile and not run ti#e

Hack 3: Creatin* Sel,4re*isterin* Classes


The Problem: (ou are "riting a progra# like a i#age editor that has hundreds o) co##ands Ho" do you ,uild a #aster co##and list The Hack: Sel) registering classes !he solution is to #ake each instance o) the class register itsel) 'or this e&a#ple "e "ill de)ine a c:d class "hich de)ines a na#ed co##and )or our editor % derived class "ill ,e created using this as a ,ase )or each co##and !he derived class is responsi,le )or de)ining a do_it )unction "hich per)or#s the actual "ork 6hen a co##and is created the c:d class "ill register it c:d&const char* const i_na:e':na:e&i_na:e' K do_register&'; L Gaturally "e have to unregister it "hen it5s destroyed* $irtual Qc:d&' K unregister&'; L -e#e#,er this is a ,ase class, so "e #ust #ake the destructor virtual %s hackers "e "ish to hide as #uch in)or#ation as possi,le )ro# the users ;n this case "e5re going to keep the list o) co##ands and the do_register and unregister )unctions entirely "ithin the class 'irst the list o) co##ands is declared as a static #e#,er varia,le* pri$ate: static std::setCclass c:d*H c:d_set;

Page 22

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

% lot o) people don5t understand "hat it #eans to declare a #e#,er varia,le static % instance o) a nor#al #e#,er varia,le is created "hen a ne" instance o) a class is created ;n other "ords a_$ar=:e:#er is a distinct and di))erent varia,le than #_$ar=:e:#er @ut static #e#,ers are di))erent 'or static #e#,er varia,le only one instance o) the varia,le is created period ;t is shared a#ong instances o) the class So in other "ords x_c:d=c:d_set is the sa#e as %_c:d=c:d_set (ou can also re)er to the varia,le "ithout an instance o) the class at all* c:d::c:d_set 06ell you could i) "e didn5t declare it private 2 Go" let5s take a look at our do_register )unction* $oid do_register&' K c:d_set=insert&this'; L !his si#ply insert a pointer to the current class into the list !he unregister )unction is Kust as si#ple* $oid unregister&' K c:d_set=erase&this'; L Go" co#es the )un one, the )unction "e call to e&ecute a co##and ;t is declared as a static #e#,er )unction so that "e #ay call it "ithout having a c:d varia,le around static $oid do_c:d&const char* const c:d_na:e' K @ecause it is static "e can call it "ith a state#ent like* c:d::do_c:d&cop%'; ote: static #e#,er )unctions can only access static #e#,er varia,les and glo,al varia,les !he ,ody o) the )unction is pretty straight )or"ard Yust loop through the set o) co##ands until you )ind one that #atches, then call the do_it #e#,er )unction static $oid do_c:d&const char* const c:d_na:e' K std::setCclass c:d*H::iterator cur_c:d; ,or &cur_c:d = c:d_set=#egin&'; cur_c:d R= c:d_set=end&'; MMcur_c:d' K Page 24 Copyright 2008, Steve Oualline

C++ Hackers Guide i, &strc:p&&*cur_c:d'NHna:e) c:d_na:e' == ;' K &*cur_c:d'NHdo_it&'; return; L L throw&un8nown_c:d&c:d_na:e''; L

Steve Oualline

One o) the #ore interesting things a,out this syste# is "hat happens "hen you use class c:d to declare a glo,al varia,le ;n that case the co##and is registered ,e)ore #ain in called ;n other "ords C++ goes through the progra# looking )or glo,al varia,les and calling their constructors ,e)ore starting each progra# (ou have to ,e care)ul "hen doing this though !here is no guarantee concerning the order in "hich the classes are initialiFed @asically you don5t "ant to create any glo,al varia,les "ho5s constructor depends on a co##and ,eing registered !he co#plete class is listed ,elo"* Jinclude CsetH class c:d K pri$ate: static std::setCclass c:d*H c:d_set; const char* const na:e; pri$ate: $oid do_register&' K c:d_set=insert&this'; L $oid unregister&' K c:d_set=erase&this'; L $irtual $oid do_it&$oid' = ;; pu#lic: c:d&const char* const i_na:e':na:e&i_na:e' K do_register&'; L $irtual Qc:d&' K unregister&'; Page 2> Copyright 2008, Steve Oualline

C++ Hackers Guide L

Steve Oualline

pu#lic: static $oid do_c:d&const char* const c:d_na:e' K std::setCclass c:d*H::iterator cur_c:d; ,or &cur_c:d = c:d_set=#egin&'; cur_c:d R= c:d_set=end&'; MMcur_c:d' K i, &strc:p&&*cur_c:d'NHna:e) c:d_na:e' == ;' K &*cur_c:d'NHdo_it&'; return; L L throw&un8nown_c:d&c:d_na:e''; L L; % s#art hacker #ight note that "e could have used a std:::ap to hold our co##and list %)ter all a std:::ap takes a key and value pair and "ould eli#inate our lookup loop in do_c:d @ut the e&tra synta& needed to #ake a std::map "ork "ould get in the "ay o) the point o) this hack So "hile the class is not as e))icient code "ise, it is very e))icient ,ook "ise

Hack 15: Deco%ple the Inter,ace and the Implementation


The Problem* C++ )orces you to e&pose the i#ple#entation details "hen you de)ine a class $et5s take a look at a typical class de)inition )or a dictionary class !his class lets you de)ine a list o) "ord pairs called the key and the value ;t then lets you use the key to lookup the value

Page 2?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

class dictionar% K pri$ate: // ots o, stu,, that the user doesn't need to // worr% a#out= // &And this is the pro#le:' pu#lic: // === usual constructor / destructor stu,, $oid add_pair&const std::string> 8e%) const std::string> $alue'; const std::string> loo8up&const std::string> 8e%'; L; !he pro,le# is that this gives anyone "ho uses this class access to so#e o) the private i#ple#entation details o) the class The Hack: Hide the i#ple#entation details through the use o) an i#ple#entation class class dictionar% K pri$ate: dictionar%_i:ple:entation* i:ple:entation; pu#lic: Since "e don5t have to de)ine dictionar%_i:ple:entation in the header )ile this e))ectively hides the i#ple#entation and separates the inter)ace and the i#ple#entation Hacking the Hack: !here are several "ays o) i#ple#enting a dictionary 'or e&a#ple, i) "e are dealing "ith a,out 10C100 "ords, "e could i#ple#ent the dictionary using an array 'or 100C100,000 entries "e could use a dyna#ic list 'or over 100,000 the code can #ake use o) an e&ternal data,ase @ut "hat5s nice a,out de)ining a dictionary in this "ay is that the class can change the i#ple#entation on the )ly as conditions change 'or e&a#ple, the class can start "ith an array 6hen the nu#,er o) entries gro"s to #ore than 100 it can s"itch to a list ,ased i#ple#entation*

Page 2A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

$oid dictionar%:: add_pair&const std::string> 8e%) const std::string> $alue' K i, &&i:ple:entationNHt%pe&' == A00AG_IP3 !P!N+A+I/N'>> &i:ple:entationNHsi<e&' H= PAS_A00AG'' K dictionar%_i:ple:entation* new_i:ple:entation = new dictionar%_as_list&i:ple:entation' delete i:ple:entation; i:ple:entation = new_i:ple:entation; L // === sa:e thing ,or list NH data#ase

i:ple:entationNHadd_pair&8e%) $alue'; !hus "e5ve not only hidden the dictionary i#ple#entation, ,ut "e5ve #ade it a,le to dyna#ically recon)igure itsel) depending on data load

Hack 11: Learnin* #rom )he Lin%&

ernel List #%nctions

The Problem: !here are lots o) "ays o) creating a linked list !here are only a )e" good ones The Hack: !he $inu& kernel5s linked list i#ple#entation 0See the )ile 1usr1include1linu&1list h in any kernel source tree 2 !here a large nu#,er o) things "e can learn )ro# this si#ple #odule 'irst since linked lists are a si#ple and co##on data structure it #akes sense to create a linked list #odule to handle the# %)ter all things can get con)used i) everyone i#ple#ents his o"n linked list :specially i) all the i#ple#entations are slightly di))erent Lesson !: Code -euse !he "ay the linked list is i#ple#ented is very e))icient and )le&i,le (ou can actually have ite#s that are put on #ultiple lists Lesson ": 'le&i,le design !he list )unctions are "ell docu#ented !he header )iles contains e&tensive co##ents using the 9o&ygen docu#entation convention 0See Hack A?2 Lesson #: Share your "ork 9ocu#ent it so others can use it

Page 2B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!here5s there5s a #echanis# in place to help persuade people to use this i#ple#entation and to avoid "riting their o"n ;) you su,#it a kernel patch containing a ne" linked list i#ple#entation you "ill ,e /politely3? told to use the standard i#ple#entation %lso your code "on5t get in the kernel until you do Lesson $: :n)orce#ent o) standard policy 8ostly through peer pressure So ,y looking at this i#ple#entation o) a si#ple linked list "e can learn so#ething 6hich leaves us "ith our )inal lesson* Lesson %: % good hacker learns ,y reading code "ritten ,y so#eone "ho kno"s #ore a,out this type o) progra##ing that you do

? !he ter# /polite3 has a di))erent #eaning "hen dealing "ith people "ho )re=uent the kernel #ailing lists

Page 28

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 2: Safet Hacks


So#e progra##ers code )irst and think a,out sa)ety later !hese are the people "ho spend the )irst si& #onths o) the career "riting code and the ne&t )ive years creating security patches $et5s suppose you are standing at the top o) a very tall cli)) (ou need to get to the ,otto# 6ould you 1 Start #oving i##ediately and Ku#p o)) the cli)) ,ecause that5s the )astest "ay to get to the ,otto# 0(ou5ll "orry a,out sa)ety a)ter you start your Ku#p 2 2 %nalyFe the terrain to discover the ,est #ethod o) getting you to the ,otto# in one piece ;) you ans"ered D1, then you code like #ost o) the progra##ing drudges out there out there ;t5s the )astest ans"er you can give i) you have a,solutely no regard )or sa)ety at all A % true hacker5s ans"er is /;5d think )or #o#ent and )igure out the )astest sa)e route !hen ;5d #ark it as ; "ent do"n to help those "ho )ollo" #e 3 C "as never designed )or sa)ety C++ ,uilds on this )oundation to create a #ore co#ple& and unsa)e language (et there are hacks "hich can use to #ake your progra#s sa)er ;n other "ords your progra# "ill crash less, and even i) they do crash, the pro,le# "ill ,e easier to )ind

Hack 12: Eliminate Side E,,ects


The Problem: C++ let5s you use operators like ++ and CC to #ake your code very co#pact ;t also can ,e used to create code that generates a#,iguous results, as "ell as ,eing unreada,le The Hack: 6rite state#ents that per)or# one operation only 9on5t use ++ and CC e&cept as standalone state#ents

A ;) you think that no progra##er "ould really progra# this "ay, Kust look at the design decisions #ade ,y a certain #aKor co##ercial operation syste# !hese people have to issue "eekly security patches to keep up "ith the sa)ety pro,le#s that they the#selves introduced ,ecause they decided to code and think in that order

Page 27

Copyright 2008, Steve Oualline

C++ Hackers Guide 'or e&a#ple, is the result o) the )ollo"ing code* i = ;; // 1ad code arra%TiMMU = i; !here are t"o su,Ce&pressions involving i !hese are* 1 i++ 2 i

Steve Oualline

!he co#piler is )ree to e&ecute the# in any order it "ants to So "hat co#piler you are using and even "hat co#pilation )lags are used can a))ect the result !here is no reason )or trying to keep everything on one line (ou co#puter has lots o) storage and a )e" e&tra lines "on5t hurt things % si#ple, "orking progra# is al"ays ,etter than a short, co#pact, and ,roken one So avoid side e))ects and put ++ and -- on lines ,y the#selves ;) "e re"rite the previous e&a#ple as* iMM; arra%TiU = i; !he order o) the operations is clear not only to the co#piler ,ut to anyone reading the code

Hack 13: Don6t '%t 7ssi*nment Statements Inside 7n! 8ther Statements
The Problem: ;t5s a classic #istake* using M instead o) MM Code like* i, &i = getch&'' K // 7o so:ething L The Hack: Gever include an assign#ent state#ent inside any other state#ent 0%ctually never include any state#ent inside any other state#ent, ,ut this one is so co##on it deserves its o"n hack 2 !he reason )or this is si#ple* (ou "ant to do t"o si#ple things right one at a ti#e 9oing t"o things at once in a co#ple&, and un"orka,le state#ent is not a good idea Page 40 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his hack )lies in the )ace o) so#e co##on design patterns 'or e&a#ple* // 7on't code li8e this while &&ch = getch&'' R= !/5' K putchar&ch'; L 'ollo"ing this sa)ety rule, our code looks like* // .ode li8e this while &true' K ch = getch&'; i, &ch == !/5' #rea8; putchar&ch'; L Go" a lot o) people "ill point out that the )irst version is a lot #ore co#pact So "hatS 9o you "ant co#pact code or sa)e codeS 9o you "ant co#pact code or understanda,le codeS 9o you "ant co#pact code or "orking codeS ;) "e take o)) the re=uire#ent that the code "orks, ; can #ake the code #uch #ore co#pact @ecause #ost people value things like code that is sa)e and "orking, it is a good idea to use #ultiple si#ple state#ents instead o) a single co#pact one !his hack is designed to keep things si#ple and constant %s a hacker "e kno" you are a clever progra##er @ut it takes a very clever progra##er to kno" "hen not to ,e clever

Hack 1(: Use const Instead o, 9de,ine When 'ossi0le


The Problem: !he &define directive de)ines a literal replace#ent !he preCprocessor is its o"n language and does not )ollo" the nor#al C++ rules !hat can lead to so#e surprises 'or e&a#ple* // .ode has lots o, pro#le:s &don't code li8e this' Jde,ine -I7+I A V ( // -idth o, page V :argin $oid print_in,o&' K // -idth in points int points = -I7+I * D*; std::cout CC -idth in points is CC Page 41 Copyright 2008, Steve Oualline

C++ Hackers Guide points CC std::endl;

Steve Oualline

Luestion* 6hat5s WIDTHS ;) you ans"ered B you got it "rong !he preC processor is a very literal progra# !he value o) WIDTH is literally 8 1 @ut everyone kno"s that 8 Q 1 is B rightS Got everyone C++ does not :specially "hen used in a e&pression !he line* int points = -I7+I * D*; is translated ,y the preCprocessor into* int points = A N ( * D*; %s a result, the value o) points is not "hat the progra##er intended The Hack: .se const instead o) &define "henever possi,le ;) "e had de)ined "idth as* static const int -I7+I = A V (; // -idth o, page V :argin then our calculations "ould ,e correct !hat5s ,ecause "e are no" de)ining WIDTH using C++ synta&, not preCprocessor synta& .sing const has another ,ene)it ;) you #ake a #istake in the &define state#ent, the pro,le# #ay not sho" up until you actually use the constant !he C++ co#piler per)or#s synta& checking on const state#ents %ny synta& pro,le#s "ith these state#ents sho" up i##ediately and you don5t have to guess "here the pro,le# occurred

Hack 1+: I, :o% M%st Use 9de,ine '%t 'arenthesis 7ro%nd )he ;al%e
The Problem: !here are so#e ti#es that you Kust can5t use const Ho" do you avoid pro,le#s like the one sho"n in the previous hackS (ou #ight ask "hy can5t "e Kust use constS !he ans"er is that so#eti#es you need to create a header )ile that5s shared "ith a progra# in another language 'or e&a#ple the h2ph progra# that co#es "ith Perl understands &define, ,ut not const The Hack* %l"ays enclose &define values in 02 'or e&a#ple* Jde,ine -I7+I &A V (' // -idth o, page V :argin Go" "hen you use this in a state#ent like* Page 42 Copyright 2008, Steve Oualline

C++ Hackers Guide int points = -I7+I * D*; you get the correct value

Steve Oualline

Hack 1.: Use inline #%nctions Instead o, 'arameteri<ed Macros Whene1er 'ossi0le
The Problem: Para#eteriFed #acros can cause une&pected things to happen Consider the )ollo"ing case* Jde,ine 6W2A0!&x' &&x' * &x'' int i = F; int X = 6W2A0!&iMM'; 6hat5s the value o) jS !he ans"er is that it5s co#piler dependent %nd the value o) i is de)initely not A 6hyS Yust look at the code a)ter the #acro is e&panded* int X = &&iMM' * &iMM''; 'ro# this "e can see that i is incre#ent t"ice %lso since the order o) the operations is not speci)ied ,y the C++ standard, the actual value o) j is co#piler dependent Gote* 6e violated Hack 12 in this e&a#ple !his is another e&a#ple o) "hy that hack is i#portant The Hack: .se inline )unctions instead o) &define "henever possi,le $et5s see ho" our code "ould look "ith an inline )unction* static inline int sYuare&int x' K return &x * x'; L Go" "hen this )unction is called t"o things happen* j gets the correct value and i is incre#ented once ;n other "ords, the code ,ehaves Kust like it is "ritten %nd having so#ething look and act the sa#e "ay is a ,eauti)ul hack ote: So#eone ;5# sure is going to point out that the #acro "orks )or any type and the inline )unction only "orks )or integers !his pro,le# is easily solved ,y #aking the inline version a )unction template

Page 44

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 1/: I, :o% M%st Use 'arameteri<ed Macros '%t 'arenthesis 7ro%nd )he ar*%ments
The Problem: !he "ay the preCprocessor handles para#eteriFed #acros can so#eti#es lead to incorrect code 'or e&a#ple* // 7on't code li8e this Jde,ine 6W2A0!&x' &x * x' So "hat5s the value o) i in the )ollo"ing state#ent* int i = sYuare&( M *'; Should ,e 7 @ut the state#ent e&pands to* int i = &( M * * ( M *'; "hich gives us ? not 7 The Hack: Put parenthesis around every place you use a para#eter in a para#eteriFed #acro 'or e&a#ple* Jde,ine 6W2A0!&x' &&x' * &x'' Go" our e&panded assign#ent state#ent looks like* int i = &&( M *' * &( M *''; and "e5ll get the right ans"er ote: !his does not solve the incre#ent pro,le#s sho"n in Hack 1A !his hack should ,e only used i) you a,solutely #ust use para#eteriFed #acros and can5t use inline )unctions 0See also Hack 12 )or help avoiding the incre#ent pro,le# 2

Hack 12: Don6t Write 7m0i*%o%s Code


The Problem: Consider the )ollo"ing code* i, &a' i, &#' do_so:ething&'; else // Indentation o,, do_so:ething_else&'; 6hich if does the else go "ithS 1 ;t goes "ith the )irst if 2 ;t goes "ith the second if Page 4> Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

4 ;) you don5t "rite code like this you don5t have to "orry a,out stupid =uestions The Hack: !he hacker5s ans"er is o,vious the third one Hackers kno" ho" to avoid trou,le ,e)ore it starts So i) "e never get near nasty code "e don5t have to "orry a,out ho" it "orks 0.nless "e have to deal "ith legacy code "ritten ,y nonChackers 2 %l"ays include OP "hen there5s any a#,iguity in your code !he previous e&a#ple should ,e "ritten as* i, &a' K i, &#' K do_so:ething&'; L else K do_so:ething_else&'; L L 'ro# this code it5s clear "hich if the else ,elongs to @eing o,vious is an i#portant part o) coding sa)ely !here5s enough con)usion and chaos in progra##ing already "ithout having so#eone add to it ,y e&ploiting o,scure ele#ents o) the C++ synta& % good hacker kno"s ho" to keep things si#ple, o,vious, and "orking

Hack 13: Don6t -e Cle1er With the 'recedence R%les


The Problem: 6hat5s the value o) the )ollo"ing e&pressionS i = ( O ? > F CC *; 8ost people "ould ans"er /; don5t kno" 3 Hackers "ould ans"er /; don5t kno",3 then "rite a short test progra# to )ind out the ans"er 0%nd ;5# not going to spoil your )un ,y putting the ans"er in here 2 @ut the pro,le# is unless you are really into the C++ standard and have #e#oriFed the 1B operator precedence rules you can5t tell "hat this code is doing The Hack: $i#it yoursel) to t"o precedence rules* 1 8ultiple and 9ivide co#e ,e)ore addition and su,traction 2 Slap parenthesis around everything else

Page 4?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Consistency and si#plicity are key to sa)e progra##ing !he less you have to think and #ake decisions the less you can #ake the "rong decision % good hacker "ill produce a set o) rules and procedures so he can do things consistently and right %nother "ay o) saying this is a good hacker does a great deal o) thinking a,out things so he doesn5t have to do a great deal o) thinking !he si#pli)ied precedence rules are one e&a#ple o) this %l#ost no one re#e#,ers the o))icial 1B, ,ut re#e#,ering the si#pli)ied t"o is si#ple %pplying our hack it5s easy to )igure out the result o) the )ollo"ing e&pression* i = &( O ?' > &F CC *'; 0; kno" it5s not the sa#e result, ,ut this is "hat the progra##er intended in the )irst place 2

Hack 25: Incl%de :o%r 8"n Header #ile


The Problem: ;t is possi,le )or a )unction to ,e de)ined one "ay in a header )ile and the other in the code 'or e&a#ple*

s=uare h
extern long int sYuare&int $alue';

s=uare cpp
int sYuare&int $alue' K return &$alue * $alue'; L ote: C++ is only partially type sa)e !he para#eters to a )unction are checked across #odules, the return values are not So "hat happens "hen this )unction is calledS !he sYuare )unction co#putes a nu#,er and returns the result, a 42 ,it integerB !he caller kno"s that the )unction returns a A> ,it integer Since 42 ,it return values and A> ,it return values are returned in di))erent registers, the calling progra# gets gar,age 6hat5s "orse the poor #aintenance progra##er is let "ondering ho" a )unction like sYuare "hich is to si#ple to )ail, is actually )ailing

B 6e assu#e "e are on a #achine "here an int is 42 ,its

Page 4A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The Hack: 8ake sure each #odule includes it5s o"n header )ile ;) the s=uare cpp )ile ,egan "ith* Jinclude sYuare=h the co#piler "ould notice the pro,le# and prevent you )ro# co#piling the code %nd pro)essional progra##ers kno" that it5s 10,000 ti#es easer to catch an o,vious pro,le# at co#pile ti#e than it is to locate a rando# value error in a running progra#

Hack 21: S!nchroni<e Header and Code #ile =ames


The Problem: !he previous hack tells us that each #odule should include it5s o"n header )ile Ho" can "e #ake that as si#ple as possi,le The Hack: %l"ays use the sa#e na#e )or ,oth the header )ile and and the code )ile So i) the header is s=uare h the code )ile "ill ,e s=uare cpp 6hen you have a rule like this you don5t have to think and avoiding e&traneous decision #aking "ill help #ake your code #ore relia,le @ut no" let5s suppose "e have three )iles s=uare cpp, round cpp, and triangle cpp !hese "ill ,e co#piled and co#,ined to )or# a li,rary li,shape a ;deally "e "ould like to supply the user "ith a single header )ile so he doesn5t have to kno" or understand our #odule structure 6hat do "e doS ;) "e supply hi# "ith a shape h )ile "e )ul)ill our si#plicity re=uire#ents, ,ut "e violate our na#ing rules !he ans"er is that "e can do ,oth, provide a single inter)ace )ile to the user and )ollo" our na#ing rules 6e start ,y creating three header )iles )or our three #odules* s=uare h, round h, and triangle h Ge&t "e create an inter)ace )ile )or the user, shape h "hich contains* Jinclude CshapeNinternal/sYuare=hH Jinclude CshapeNinternal/round=hH Jinclude CshapeNinternal/triangle=hH !he nice thing a,out this syste# is that our header )iles #irror our o,Kect )iles 6e asse#,le a ,unch o) o,Kect )iles into a li,rary and our group header shape h asse#,les a ,unch o) header )iles into a #aster header )or the user One o) the ,est )or#s o) hacking is to si#pli)y things % good hacker does a lot o) thinking and design so he doesn5t have to do a lot o) thinking or design

Page 4B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 22: =e1er )r%st User Inp%t


The Problem* .sers type in ,ad things 8ost users type in ,ad things ,ecause they don5t understand the so)t"are or understand it5s li#itation !hey can look at a pro#pt like* !nter a user na:e &F characters onl%': 7o not t%pe in :ore than F characters= It won't wor8= 5i$e character is the li:it no :ore= A#solutel% no :ore than F characters please= 2ser na:e: and see an open invitation to type in )i)tyC)ive characters Stupid users enter ,ad data S#art users "ho think they kno" #ore than the co#puter enter ,ad data %verage users #istype things and enter ,ad data ; think "e can set the pattern here 6hat5s "orse is the #alicious user "ho enter ,ad data in an e))ort to crash the syste# or ,ypass security !"o classic attack vectors are the stack s#ashing attack and the SL$ inKection techni=ue ;n stack s#ashing attack the user atte#pts to over)lo" the input ,u))er ;) he inputs enough data he can over"rite the return address in the stack and trick the co#puter in e&ecuting ar,itrary code !o protect against stack s#ashing attack al"ays check the length o) user input to #ake sure that the li#it is o,eyed ;) you are using C style ;1O this #eans using )gets instead o) gets 0See Hack 24 ,elo" 2 SL$ ;nKection attacks involve the user su,#itting ,adly )or#ed data in hope that it5s e&ecuted in an SL$ =uery 'or e&a#ple, the )ollo"ing SL$ code updates a user :C8ail address* 237A+! user_in,o 6!+ e:ail = ',redZwhate$er=co:' -I!0! user = '5red'; !hings go Kust )ine i) the user tells you his na#e is /5red @ut a #alicious user can play ga#es "ith the user na#e 'or e&a#ple, let5s suppose he gives us a user na#e o) /5';6! !.+ user) password 50/P user_in,o;3 Go" our SL$ co##and is* 237A+! user_in,o 6!+ e:ail = ',redZwhate$er=co:' -I!0! user = '5';6! !.+ user) password 50/P user_in,o; @etter "ritten as*

Page 48

Copyright 2008, Steve Oualline

C++ Hackers Guide 237A+! user_in,o 6!+ e:ail = ',redZwhate$er=co:' -I!0! user = '5'; 6! !.+ user) password 50/P user_in,o;

Steve Oualline

!he '(L(CT state#ent "ill return to the user all the user na#es and pass"ords in the data,ase )ood *+ 'ecurity Practices !he data,ase sche#a in this e&a#ple illustrates a poor data,ase design (ou never should sort sensitive in)or#ation 0pass"ord, social security nu#,er, credit card nu#,ers2 in any data,ase accessi,le directly )ro# the ;nternet Such in)or#ation should ,e kept in a dedicated secure co#puter "hich allo"s very li#ited access )ro# your o"n co#puters and no access )ro# any else ;t should ,e locked up tight %lso the data itsel) should ,e encrypted "ith a key that #ust ,e entered on the console o) the #achine at ,oot ti#e Only under e&tre#ely li#ited circu#stances should unencrypted data ,e trans#itted !he client 1 server connection should also ,e locked do"n as "ell !he client should never ,e a,le to ask the data,ase )or the pass"ord !he only thing it should ,e a,le to do is to ask /;s this pass"ord correctS3 %nd that =uestion should ,e trans#itted over an encrypted link )or added security $ooking up this data this "ay is not )oolproo), ,ut it does keep out #ost o) the ,ad guys %nd ,y the "ay storing sensitive data on a laptop or porta,le drive, especially credit card nu#,ers and social security nu#,ers is really, really stupid 9o not store sensitive in)or#ation on porta,le devices and don5t leave such devices in places like a hotel roo# "here they are easy to steal %lso any sensitive data on your laptop should ,e protected ,y a good encryption syste# !o prevent SL$ inKection attacks you should validate all the characters supplied ,y the user Here5s an e&a#ple o) ho" not to do it* Page 47 Copyright 2008, Steve Oualline

C++ Hackers Guide // 1ad code #ool $alidate_na:e&const char* const na:e' K ,or &int i = ;; na:eT;U R= '@;'; MMi' K i, &na:eTiU == '@''' return &,alse'; L return &true'; L

Steve Oualline

6hy is this code ,adS @ecause it only checks )or a ,ad character %ctually in SL$ there are #ore ,ad characters out there (ou shouldn5t check to #ake sure that the input does not contain ,ad character, you should #ake sure that everything is good // "ood code #ool $alidate_na:e&const char* const na:e' K ,or &int i = ;; na:eT;U R= '@;'; MMi' K i, &R isalnu:&na:eTiU'' return &,alse'; L return &true'; L ;t is #uch #ore secure to only good stu)) than to e&clude ,ad stu)) !hat5s ,ecause i) you #ake a #istake and #ake your /good stu))3 de)inition too restrictive you don5t cause a security hole in the progra# ;) you #ake a #istake in a /,ad stu))3 de)inition, ,ad things could get through -e#e#,er, Kust ,ecause you5re paranoid, it doesn5t #ean they aren5t out to get you

Hack 23: Don6t %se *ets


@y no" al#ost everyone kno"s the all the security and relia,ility pro,le#s that can occur "ith gets @ut it5s included here )or historical reasons as "ell ,ecause it5s a very good e&a#ple o) ,ad progra##ing $et5s look at all the pro,le#s "ith the code* // 0eall% #ad code char lineT(;;U; gets&line'; @ecause gets does not do ,ounds checking a string longer than 100 characters "ill over"rite #e#ory ;) you5re lucky the progra# "ill Kust crash Or it #ight e&hi,it strange ,ehavior

Page >0

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut this code is also a security pro,le# % attacker can create a care)ully constructed string "hich over"rites the stack and let5s the ,ad guy e&ecute any code he "ants to !he gets )unction is so ,ad that the GG. gcc linker issues a "arning "henever it5s used
9tm#9cc:%;<%m.o4.te8t.08246: :n +!nction 3main7: : warnin": t e 3"ets7 +!nction is dan"ero!s and s o!ld not 'e !sed.

The Hack: .se ,gets instead // "ood code char lineT(;;U; ,gets&line) si<eo,&line') stdin'; !he ,gets call "ill not get #ore data than the varia,le can hold !his prevents attackers )ro# e&ecuting a stack s#ashing attack

Hack 2(: #l%sh De0%**in*


The Problem: @u))ering o) output can lead to une&pected results 'or e&a#ple* std::cout CC 7oing unrelated stu,, CC std::endl; do_stu,,&'; std::cout CC 7oing di$ide === ; i = (/;; // 7i$ide #% <ero std::cout CC co:plete@n; 6hen runs this progra# prints 0on so#e syste#s2* 7oing unrelated stu,, 5loating point exceptionA 'ro# this output "e can see that the pro,le# is /o,viously3 in the do_stuff )unction 6hat5s going onS !he pro,le# is that output is ,eing ,u))ered So the string

Doing di ide !!!" goes into the ,u))er, then the progra# crashes "ith a
divide ,y Fero error, and the output is never displayed !his is "here the con)usion co#es )ro#
8 6hy an integer divide ,y Fero causes a )loating point e&ception is a =uestion that this ,ook does not deal "ith

Page >1

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The Hack: 8ake sure that "hen de,ugging that the ,u))er is )lushed a)ter every output !here are several "ays o) doing this !he )irst is to e&plicitly )lush every state#ent* std::cout CC 7oing di$ide === CC std::,lush; !his "orks, ,ut you have to re#e#,er to do the )lush )or every state#ent !he other "ay is to set the unit#uf )lag "hich tells C++ to )lush a)ter every output operation !his only has to ,e done once at the top o) your progra# std::cout CC std::unit#u,; // 5ro: now on e$er%thing is auto:aticall% ,lushed ;n C the sa#e thing can ,e acco#plished ,y setting the _I$%&' )lag using the set #uf )unction* static char #u,TF(*U; // 1u,,er ,or standard out set$#u,&stdout) #u,) _I/N1V) si<eo,&#u,''; @eing a"are o) "hat5s going inside the progra# is very use)ul to a hacker So#eti#es the co#piler, li,rary or the #achine "ill do strange things to you @ut kno"ing the internals is only hal) the ,attle <no"ing ho" to get around the internal li#itations o) the syste# is the #ark o) a good hacker

Hack 2+: 'rotect arra! accesses "ith assert


The Problem: C++ does not do ,ounds checking 'or e&a#ple the )ollo"ing code "ith co#pile and e&ecute Kust )ine ;t "ill also corrupt #e#ory* // 1ad code int dataT(;U; // === int i = ((; dataTiU = F; // Pe:or% corruption The Hack: .se assert to check all array accesses 'or e&a#ple* // 1etter code Jinclude CcassertH

Page >2

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

int dataT(;U; // === int i = ((; assert&&i H= ;' >> &i C (;''; // "ood exa:ple // 0otten i:ple:entation dataTiU = F; !his "orks ,ut there is a pro,le# "ith 6e5ve used the constant 10 in t"o places 0!he declaration and the assert 2 ;t "ould ,e easy )or so#eone to change one and not the other One solution to this is to use na#ed constants // 1etter code Jinclude CcassertH const int 7A+A_6I[! = (;; int dataT7A+A_6I[!U; // === int i = ((; assert&&i H= ;' >> &i C 7A+A_6I[!''; // 1etter) // #ut not #est dataTiU = F; ;deally "e don5t "ant to have to use even na#ed constants i) "e can help it ;t is possi,le to create a ,ounds checking assert using the data varia,le alone* assert&&i H= ;' >> &i C si<eo,&data' / si<eo,&dataT;U'''; So "hat is going on hereS !he e&pression si<eo,&data' returns the nu#,er o) ,ytes in the array data @ut "e need the nu#,er o) ele#ents in the varia,le, not the nu#,er o) ,ytes !he solution is to divide the nu#,er o) ,ytes in the array ,y the nu#,er o) ,ytes in the )irst ele#ent !he result is an e&pression "hich gives us the nu#,er o) ele#ents si<eo,&data' / si<eo,&dataT;U' Go" ,eing true hackers, "e don5t "ant to have to "rite the sa#e e&pression over and over again, so let5s create a #acro to #ake our li)e easier /* * assert_#ounds&$ar) index' V Pa8e sure an index is in * #ounds= * * -arning: +his onl% wor8s is $ar is a arra% $aria#le and * not a pointer= Page >4 Copyright 2008, Steve Oualline

C++ Hackers Guide */ Jde,ine assert_#ounds&$ar) index' @ assert&&index H= ;' >> &index C &si<eo,&$ar' / si<eo,&$arT;U'''';

Steve Oualline

@ecause "e5re such nice progra##ers "e5ve docu#ented our #acro and even included a "arning descri,ing its li#itations %rray over)lo"s are one o) the #ost co##on progra##ing errors and are e&tre#ely )rustrating to try and locate !his code doesn5t eli#inate the#, ,ut it does cause ,uggy code to a,ort early in a "ay that #akes the pro,le# tre#endously easier to )ind Warning: !he assert state#ent is not guaranteed to a,ort your progra# 'or e&a#ple, consider the state#ent* assert&,alse'; !his state#ent /o,viously3 "ill cause the progra# to a,ort ,ecause the assert is al"ays )alse ;) the progra# is co#piled "ith N7!12" de)ined, all the asserts are co#piled out ;n other "ords, i) N7!12" is de)ined the previous state#ent does nothing , -eal 'ystem Crash (ou should only use assert in progra#s "here a,orting is an accepta,le ,ehavior ;n #ost cases "hen a progra# crashes it is an annoyance )or the user ,ut not a disaster !hat is not al"ays the case ;n 177A so#e people started running a progra# on an upgraded hard"are plat)or# %s a result o) the hard"are upgrade the progra# ran longer than e&pected and one o) the counters over)lo"ed Since this "as %9% code, it triggered an e&ception !he e&ception "as not caught so the syste# e&ecuted the de)ault e&ception handler and halted the processor !his "as not a good thing to do !he hard"are plat)or# that had ,een upgraded "as the %riane > rocket to the %riane ? rocket !he co#puter in =uestion "as tasked "ith keeping the rocket pointed into the air

Page >>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!echnically the rocket didn5t crash !he launch director ,le" it up "hen it started to head )or the ground !he cost o) that ,ug "as esti#ated to ,e a,out R?00,000,000 0.S2

Hack 2.: Use a )emplate to Create Sa,e 7rra!s


The Problem* (ou don5t "ant to have to add asserts every ti#e you access an array The Hack: Hide the code inside a te#plate !hen the "ork is done )or you auto#atically* Jinclude CcassertH te:plateCt%pena:e arra%_t%pe) unsigned int si<eH class arra% K pri$ate: static const unsigned int A00AG_6I[! = si<e; arra%_t%pe dataTA00AG_6I[!U; pu#lic: arra%&$oid' KL; arra%&const arra%> other_arra%' K :e:cop%&data) other_arra%=data) si<eo,&data''; L; Qarra%&' KL; arra%> operator = &const arra%> other_arra%' K :e:cop%&data) other_arra%=data) si<eo,&data''; return &*this'; L; pu#lic: arra%_t%pe> operatorTU&int index' K assert&index H= ;'; assert&index C A00AG_6I[!'; return &>dataTindexU'; L L; !his class has several nice )eatures !he )irst is that the copy constructor and the assign#ent operator are i#ple#ent in a "ay that allo"s )or copying the array @ut the ,ig advantage o) the code is the )unction "hich handles the access to an ele#ent in the array ;t includes assert state#ents "hich prevent you )ro# over)lo"ing the array* Page >? Copyright 2008, Steve Oualline

C++ Hackers Guide arra%_t%pe> operatorTU&int index' K assert&index H= ;'; assert&index C A00AG_6I[!'; return &>dataTindexU'; L

Steve Oualline

%nother )eature o) this te#plate is that it doesn5t provide a "ay o) converting an array into a pointer ;t is up to you "hether or not you consider this a )eature or a ,ug

Hack 2/: When Doin* =othin*> -e 801io%s 70o%t It


The Problem: !he )ollo"ing code is con)using // Ver% #ad coding st%le int i; ,or &i = ;; ,ooTiU R= '@;'; MMi'; std::cout CC 0esult CC i CC std::endl; %t )irst glance it see#s that so#eone )ailed to indent the progra# properly !he std::cout line should ,e indented as it is part o) the for state#ents @ut on close inspection you can see that the progra# is indented correctly !here a tiny se#icolon at the end o) the for loop* ,or &i = ;; ,ooTiU R= '@;'; MMi'; !his se#icolon is al#ost co#pletely invisi,le ;t "ould ,e nice to #ake it #ore visi,le The Hack: 9o nothing =uietly %l"ays put so#ething in to say that you5re doing nothing // Al:ost adeYuate coding st%le ,or &i = ;; ,ooTiU R= '@;'; MMi' /* 7o nothing */; !his is ,etter, ,ut "e can i#prove on it !he continue key"ord tells C++ to start the loop over again ;t can ,e placed inside our e#pty loop to provide a #ore #eaty state#ent )or our eyes* // "ood coding st%le ,or &i = ;; ,ooTiU R= '@;'; MMi' continue;

Page >A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 22: End E1er! Case "ith 0reak or ?@ #all )hro%*h @?


The Problem: ;n the )ollo"ing code did the progra##er intend )or the

6+A+!_A 3IA case to )all through or did he #ake a #istakeS ;n other "ords is that )act that 6+A+!_A 3IA calls do_alpha and do_#eta intentional or an
errorS // 0otten code switch &state' K case 6+A+!_A 3IA: do_alpha&'; case 6+A+!_1!+A: do_#eta&'; #rea8; // ==== 'ro# this code it5s i#possi,le to tell "hat the progra##er intended The Hack: @e o,vious a,out "hat you do ;) you intend )or one case to )all through to another indicate it "ith a co##ent like // 5all +hrough // 7ecent code switch &state' K case 6+A+!_A 3IA: do_alpha&'; // 5all through case 6+A+!_1!+A: do_#eta&'; #rea8; // ==== %)ter all ,eing a hacker #eans that you have to ,e clever, not that you have to ,e sneaky

Hack 23: 7 Simple assert Statements #or Impossi0le Conditions


The Problem: 6hat do you do "hen you detect an internal error (ou could do an assert&,alse'; ,ut that doesn5t give you #uch in)or#ation "hen the progra# dies The Hack: Put a #essage in your assert state#ents 'or e&a#ple* i, &this_is_not_possi#le' K assert&IN+!0NA !00/0: I:possi#le condition == ;'; Page >B Copyright 2008, Steve Oualline

C++ Hackers Guide a#ort&'; L

Steve Oualline

!he code string == ; co#pares the address o) the string against 0 !hey should not ,e Fero and the assert )ails Since a )ailing assert prints the condition that )ailed, no" "hen your progra# dies, you "ill get a nice error #essage telling you "hat happens @ut i) the progra# dies "hen the assert state#ent )ails, "hy put in the a,ortS ,ecause it5s possi,le to use co#pile ti#e s"itched 0N7N7!12"2 to co#pile out the assert state#ents So "hat this code really says, is die "ith a nice error #essage %nd i) you5re still alive, Kust die

Hack 35: 7l"a!s Check ,or )he Impossi0le Cases In s"itches


The Problem: % varia,le can only contain vo"els 6hat do you do i) it has the value 'Y'S Lousy -iddle Time L* 6hat ti#e is it "hen you clock strikes 14S %* !i#e to get a ne" clock ;n our e&a#ple here, a value o) 5Y' indicates an internal error %)ter all its /i#possi,le3 )or us to get a value o) 'Y' @ut that doesn5t stop us )ro# getting one So#eone upstrea# ,le" it !here are t"o #aKor rules o) progra##ing sa)ety* 1 Gever trust data created ,y code you didn5t "rite 2 Gever trust data created ,y code you did "rite % good dose o) paranoia is very healthily "hen it co#es to creating sa)e progra# %)ter all Kust ,ecause your paranoid, doesn5t #ean that the syste# isn5t out to get you The Hack: 8ake the s.itch state#ent take care o) everything C even the stu)) that can5t e&ist

Page >8

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

S"itches i) so#ething can have only have a li#ited nu#,er o) values, you should al"ays add a default clause to catch things that )all out o) range* switch &$owel' K case 'e': MMe_count; #rea8; case 'i': MMi_count; #rea8; case 'a': case 'o': case 'u': // Ignore these $alues #rea8; de,ault: assert&IN+!0NA !00/0: Vowel not legal == ;'; a#ort&'; L One thing to notice a,out this code, "e clearly indicate "hat vo"els are to ,e ignored ,y the state#ent* // Ignore these $alues %)ter all, the idea is to not only ,e sa)e ,ut to ,e clear and o,vious as "ell

Hack 31: Create 8pa$%e )!pes AHandlesB Which can 0e Checked at Compile )ime
The Problem: (ou are creating an %P; "hich uses a lot o) handles 'or e&a#ple, )ont handles, graphics handles, "indo" handles, color handles, and so )orth One solution is to create a /di))erent3 type )or each handle* // 7angerous code t%pede, short int t%pede, short int t%pede, short int t%pede, short int ,ont_handle; graphic_handle window_handle; color_handle;

!he )ollo"ing code sho"s these types in operation* ,ont_handle the_,ont = ,ind_,ont&+i:es) (;) 1old'; color_handle the_color = ,ind_color& ight 0ed'; draw_text&the_,ont) the_color'; Page >7 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut there is a pro,le# "ith doing things this "ay @oth ,ont_handle and color_handle have the sa#e ,asic type So the co#piler "ill not co#plain i) you do the )ollo"ing* // 3ara:eters #ac8wards draw_text&the_color) the_,ont'; ;deally "e "ould like a solution "here the co#piler "ill co#plaint i) "e #i& the handles !he other re=uire#ent "e have is that the handle take up as little space as possi,le, pre)era,le t"o ,ytes The Hack* .se a s#all structure to hold the handles $et5s take a look at the )ollo"ing handle declarations* // 6a,e code t%pede, struct K short int handle; L ,ont_handle; t%pede, struct K short int handle; L graphic_handle t%pede, struct K short int handle; L window_handle; t%pede, struct K short int handle; L color_handle; So "e5ve replaced a t"o ,yte integer "ith a t"o ,yte structure 6hat5s the ,ig dealS !he ,ig deal is type checking Go" the handles have a di))erent structure and no co##on ,ase type %s a result, the co#piler "ill do type checking ;n other "ords the )ollo"ing is legal* draw_text&the_,ont) the_color'; and the )ollo"ing is not* draw_text&the_color) the_,ont'; // Incorrect and illegal Gote all the advantages o) the handle syste# are still in places Handles are still s#all opa=ue entities, ,ut no" they are type checked as "ell !hus "e "e have a hack that gets around C++5s "eek types and turns the# into stronger ones Page ?0 Copyright 2008, Steve Oualline // .orrect and legal

C++ Hackers Guide

Steve Oualline

Hack 32: Usin* si<eo, When Ceroin* 8%t 7rra!s


The Problem: .sing na#ed constants in :e:set calls "ill )ail i) the constants get out o) sync 'or e&a#ple* // 1ad code const int ./NN!.+I/N_IN5/_6I[! = (;;; char connection_in,oT./NN!.+I/N_IN5/_6I[!U; const int 6IP3 !_./NN!.+I/N_IN5/_6I[! = ?;; char secure_connection_in,oT6IP3 !_./NN!.+I/N_IN5/_6I[!U; //=== // [ero all connection in,or:ation :e:set&connection_in,o) '@;') ./NN!.+I/N_IN5/_6I[!'; // Pista8e :e:set&secure_connection_in,o) '@;') ./NN!.+I/N_IN5/_6I[!'; !he last state#ent uses the "rong constant and Feros out the the entire array and then so#e corrupting #e#ory 8e#ory corruption is one o) the #ost di))icult pro,le#s to de,ug ,ecause it can cause strange )ailures in parts o) the code )ar )ro# the initial pro,le# The Hack: %l"ays use si<eo,&' to deter#ine the siFe o) a structure So the proper "ay o) handling doing a :e:set calls is* :e:set&arra%) '@;') si<eo,&arra%''; Go #atter ho" you change the siFe and ,ase type o) the array the

si<eo,&' operator "ill return the correct siFe and the :e:set call "ill do the
right thing

Hack 33: Use si<eo,A1arB Instead o, si<eo,At!peB in memset Calls


The Problem: .sing si<eo,&t%pe' in a :e:set call is unsa)e

Page ?1

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

So#e progra##ers consider the )ollo"ing good progra##ing practice* //Not a good idea struct data_struct K int i() i*; L; data_struct* data_ptr; data_ptr = new data_struct; //==== //1ad code :e:set&data_ptr) '@;') si<eo,&data_struct''; % pro,le# can occur i) you #odi)y the code to and #odi)y "hat data_ptr is pointing to // +his code contains a :ista8e struct data_struct K int i() i*; L; struct data_struct_i:pro$ed K int i() i*; int extra_data; L; data_struct_i:pro$ed* data_ptr; data_ptr = new data_struct_i:pro$ed; //==== // Pista8e :e:set&data_ptr) '@;') si<eo,&data_struct''; ;n the real "orld, there5s going to ,e a lot o) code ,et"een the declaration o) data_ptr and the line clearing it* :e:set&data_ptr) '@;') si<eo,&data_struct''; So the progra##er can ,e )orgiven i) he didn5t see this line "hen he changed the type o) the varia,le data_ptr @ut and error has still ,een introduced and this is not good The Hack: .se si<eo,&*ptr' to deter#ine the siFe o) dyna#ic data Go #atter ho" you change the type o) data_ptr, the e&pression si<eo,&*data_ptr' "ill al"ays contain the right nu#,er o) ,ytes So this code al"ays "orks* Page ?2 Copyright 2008, Steve Oualline

C++ Hackers Guide :e:set&data_ptr) '@;') si<eo,&*data_ptr'';

Steve Oualline

Hack 3(: Cero 8%t 'ointers to 71oid Re%se


The Problem: -eusing pointers can corrupt #e#ory %)ter a pointer is deleted 0or )reed2 it should not longer ,e used !hat doesn5t prevent ,ad code )ro# using it though So#eti#es this results in a rando# corruption o) #e#ory, one o) the toughest pro,le#s to de,ug Here5s an e&a#ple o) "hat "ere talking a,out* int* data; data = new intT(;U; dataT;U = ;; // === lots :ore wor8 with data === deleteTU data; // === a ,ew thousand lines o, code === dataT*U = *; // Pe:or% corruption The Hack: Set the pointer to N2 'or e&a#ple* deleteTU data; data = N2 ; !he result is that on #ost syste#s i) you try and use the pointer, the syste# "ill crash* // === a ,ew thousand lines o, code === dataT*U = *; // 6%ste: crashes !his hack does not prevent errors, ,ut it does change the# %ccessing a #e#ory pointer a)ter it is deleted can result in data corruption or heap corruption !he results o) this error #ay not sho" up )or a long ti#e and "ill pro,a,ly happen "hen you are e&ecuting a totally unrelated piece o) code On the other hand, i) the pointer has ,een set to N2 , then an atte#pt to use "ill usually result in a syste# crash as the point o) use So ,y resetting pointers a)ter each use you change a hard to )ind, rando# error, into one that repeata,le and easy to )igure out a)ter deleting it

Page ?4

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 3+: Use strncp! Instead o, strcp! )o 71oid -%,,er 81er,lo"s


The Problem: !he )unction strcp% is unsa)e !he )ollo"ing code over)lo"s an array and corrupts #e#ory // 1ad code char na:eT(;U; strcp%&na:e) 96te$e /ualline9'; The Hack: .se strncp% !he )unction strncp% copies a string, ,ut only a li#ited nu#,er o) characters ;) "e add to this the si<eo,&' operator "e can ,e assured that "e "ill never copy #ore data than the destination can hold So a sa)er string copying #ethod is* // 3artial solution strncp%&na:e) 96te$e /ualline9) si<eo,&na:e''; @ut there5s a catch -eading the docu#entation )or strncp% "e )ind the )ollo"ing paragraph*
T e strnc#y46 +!nction is similar =to strc#y>, e8ce#t t at not more t an n 'ytes o+ src are co#ied. T !s, i+ t ere is no n!ll 'yte amon" t e +irst n 'ytes o+ src, t e res!lt will not 'e n!ll-terminated.

6e "ant the result to al"ays ,e null ter#inated, so "e e&plicitly handle the e&ception case and #ake sure that our string is null ter#inated %gain, "e use the si<eo,&' operator to #ake sure "e get the right siFe na:eTsi<eo,&na:e'N(U = '@;'; Putting this all together "e get the code* // "ood code char na:eT(;U; strncp%&na:e) si<eo,&na:e') 96te$e /ualline9'; na:eTsi<eo,&na:e'N(U = '@;'; Warning: !he si<eo,&na:e' only "orks i) na#e is declared as an array ;) it is declared as a pointer, then si<eo,&na:e_ptr' returns the siFe o) the pointer, not the data that it is pointing to

Page ?>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

ote: ;t is possi,le to avoid all C style string related #e#ory pro,le#s ,y using C++ std:::string strings @ut a lot o) code still uses the old style strings and there are per)or#ance issues "ith C++ strings ote: % ne" )unction called strlcp% has ,een introduced in so#e C1C++ li,raries "hich allo"s )or sa)e string copies Ho"ever, it5s not standard, it5s not in all li,raries, and Solaris and Open@S9 have i#ple#ented it di))erently @ut i) you have it, ,y all #eans use it

Hack 3.: Use strncat instead o, strcat ,or sa,et!


The Problem: strcat is unsa)e !he )ollo"ing code over)lo"s the array na#e and corrupts #e#ory // 1ad code char na:eT(;U; strncp%&na:e) 9/ualline9) si<eo,&na:e''; na:eTsi<eo,&na:e'N(U = '@;'; strcat&na:e) 9) 9'; strcat&na:e) 9/ualline'; // Pe:or% is now corrupt ote: 9e)ining an array using a nu#eric constant 0(;2 instead o) a na#ed constant 0NAP!_6I[!2 is ,ad progra##ing practice @ut it does #ake the e&a#ple si#pler, so it5s good "riting practice "hen e&plaining a hack The Hack: %l"ays use strncat $et5s re"rite the previous e&a#ple using sa)e progra##ing hacks 'irst "e sa)ely copy /ualline into the na:e varia,le Ge&t "e use strncat to add on the Zco##a[, Zspace[ characters !he =uestion is ho" #any characters can "e put in the arrayS !he varia,le na:e "ill hold up to 10 characters @ut to ,e sa)e "e spell 10 as si<eo,&na:e' 6e5ve already used up strlen&na:e' characters, so the )ree space in the varia,le is denoted ,y the e&pression* si<eo,&na:e' V strlen&na:e' // Inco:plete 6e need one ,yte )or the end o) string character So let5s add it to our e&pression* Page ?? Copyright 2008, Steve Oualline

C++ Hackers Guide si<eo,&na:e' V strlen&na:e' N(

Steve Oualline

Putting it all together "e get this sa)e version o) the progra#* // "ood code char na:eT(;U; strncp%&na:e) 9/ualline9) si<eo,&na:e''; na:eTsi<eo,&na:e'N(U = '@;'; // .oncatenation exa:ple strncat&na:e) 9) 9) si<eo,&na:e' V strlen&na:e' N('; na:eTsi<eo,&na:e'N(U = '@;'; // +his is reYuired strncat&na:e) 9/ualline) si<eo,&na:e' V strlen&na:e' N('; na:eTsi<eo,&na:e'N(U = '@;'; ote: % ne" )unction called strlcat has ,een introduced in so#e C1C++ li,raries "hich allo"s )or sa)e string catenation Ho"ever, it5s not standard, it5s not in all li,raries, and Solaris and Open@S9 have i#ple#ented it di))erently @ut i) you have it, ,y all #eans use it

Hack 3/: Use snprint, )o Create Strin*s


The Problem: 6hen using sp(intf it5s possi,le to "rite data to the string that5s longer than the string 'or e&a#ple* char ,ileT(;U; sprint,&,ile) /$ar/t:p/prog/session/\d) pid'; The Hack: .se snp(intf instead !he second para#eter to snp(intf is the siFe o) the string ;n keeping "ith our other sa)ety hacks, "e use si)eof*string+ in this para#eter "henever possi,le Since snp(intf kno"s the siFe o) the string, it is s#art enough not to over)lo" it So the )ollo"ing code "ill not #ess up #e#ory !he )ile na#e "ill ,e a little short, ,ut at least you "on5t have to deal "ith #e#ory corruption char ,ileT(;U; snprint,&,ile) si<eo,&,ile') /$ar/t:p/prog/session/\d) pid';

Page ?A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 32: Don6t Desi*n in 7rti,icial Limits


The Problem: %ny ti#e you design code "ith an arti)icial li#it so#eone "ill e&ceed it 'or e&a#ple, consider the code* $oid err&const char* const ,:t) int a = ;) int # = ;) int c = ;) int d = ;) int e = ;' K ,print,&stderr) 95atal !rror:@n9'; ,print,&stderr) ,:t) a) #) c) d) e'; ,print,&stderr) 9@n9'; a#ort&'; L Go" this "orks i) you "ish to "rite si#ple #essages* err&6i<e para:eter &\d' out o, range) si<e'; @ut "hat happens "hen "e "ish to a slightly #ore co#ple& callS err&3oint &\d)\d' outside o, #ox &\d)\d') &\d)\d') point=x) point=%) #ox=x() #ox=%() #ox=x*) #ox=%*'; Our )unction can take a )or#at and up to )ive para#eters 6e Kust gave it si& ;t5s not going to "ork Go" "e could )i& the err )unction to add another para#eter, ,ut that "ould only "ork until "e needed seven para#eter %nother change "ould ,e needed at eight and so on The Hack: 6hen "riting general )unctions don5t design yoursel) into a corner ;) you really kno" the C++ language then you kno" ho" to design an err )unction that takes any nu#,er that takes any nu#,er o) para#eters* Jinclude CcstdargH $oid err&const char* const ,:t) ===' K $a_list args; $a_start&args) ,:t'; ,print,&stderr) 95atal !rror:@n9'; $,print,&stderr) ,:t) args'; ,print,&stderr) 9@n9'; a#ort&'; L !his is not the only place "here arti)icial li#its can cause trou,le %ny ti#e you design li#its into the syste#, sooner or later so#eone "ill e&ceed the# Page ?B Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

One classic e&a#ple o) an ar,itrary li#itation "as the A>0< li#itation % =uote attri,uted to @ill Gates7 states /A>0< ought to ,e enough #e#ory )or anyone 3 @ut it "as only a short "hile a)ter the original PC ca#e out that people started inventing addCon cards "ith special drivers designed to get around the A>0< li#itation %nother e&a#ple is the ls co##and !he initial version used single characters )or options 0-l, -,, etc 2 9o a #an ls no" and you5ll )ind that al#ost all the single letters 0upper and lo"er case2 are ,eing used ,y this co##and 'i)ty t"o 02AH22 options "ere Kust not enough @y li#iting options to a single character the designers o) ls li#ited their e&panda,ility So#eone had to devise a ne" option synta& 0--long-options2 to get around this pro,le# The 'enior Citi/en Truant One state5s citiFen tracking syste# li#ited a person5s age to t"o digits So "hen one o) its citiFens reached 100 her age "as reset to 0 !his "asn5t too ,ig a pro,le# !he real trou,le ca#e "hen she reached 10B and the state sent a truant o))icer out to her house to )ind out "hy her parents had not enrolled her in the )irst grade

Hack 33: 7l"a!s Check ,or Sel, 7ssi*nment


The Problem: ;t is possi,le to create code that per)or#s the )ollo"ing operation on a class* x = x; ;n real li)e sel) assign#ent is pro,a,ly not going to ,e as o,vious as this ;nstead it "ill pro,a,ly ,e hidden ,y a couple or #ore layers o) )unction calls @ut "hen this does occur the results can ,e catastrophic Consider the )ollo"ing assign#ent operator pseudo code* a_class> opeator = &const a_class> other_one' K (= 7elete :% data *= Allocate a new structure the sa:e si<e as other_one's data ?= .op% o$er the data !he code )or this class is* class a_class K
7 8r Gates has denied saying this

Page ?8

Copyright 2008, Steve Oualline

C++ Hackers Guide pri$ate: unsigned int si<e; char* data; pu#lic: a_class&unsigned int i_si<e' K si<e = i_si<e; data = new charTsi<eU'; L // Iere's the pro#le: code a_class operator = &const> a_class other' K deleteTU data; data = N2 ; si<e = other=si<e; data = new charTsi<eU; :e:cp%&data) other=data) si<e'; L L

Steve Oualline

Go" consider "hat happens "hen a varia,le is assigned to itsel) !he )irst step* (= 7elete :% data deletes the data )or the destination varia,le 0*this2 Ho"ever, the destination varia,le is also the source varia,le 0other_one2, the data )or this is deleted as "ell ;n )act the only copy o) the data is deleted !he progra# "ill )ail "hen "e get to the step* *= Allocate a new structure the sa:e si<e as other_one's data ,ecause there is no data in other_one, "e deleted it in step 1 The Hack: Progra# de)ensively and check )or sel) assign#ent e&plicitly :very nonCtrivial class should have the )ollo"ing at the ,eginning o) each assign#ent operator )unction* a_class> opeator = &const a_class> other_one' K i, &this == >other_one' return &*this'; // 6el, assign:ent detected // ==== !his little ,it o) insurance can prevent a really nasty pro,le# )ro# occurring

Page ?7

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack (5: Use Sentinels to 'rotect the Inte*rit! o, :o%r Classes


The Problem: Strange things are happening to one o) your classes 9ata is getting corrupted so#eho" (ou suspect so#eone is "riting over rando# #e#ory, ,ut ho" do you prove it* The Hack: Put sentential at the ,eginning and end o) your class and check the# o)ten 'or e&a#ple* class no_sto:p K pri$ate: enu: K6+A0+_PA"I. = ;x(*?BFEDA) !N7_PA"I. = ;xADEFB?*(L; // +his :ust #e the ,irst constant or $aria#le // declared= It protects the class against // nast% code o$erwriting it= const long unsigned int start_sentinel; // ==== pu#lic: no_sto:p&': start_sentinel&6+A0+_PA"I.') end_sentinel&!N7_PA"I.' KL // ==== // !$er% :e:#er ,unction should call this // to :a8e sure that e$er%thing is still /4= chec8_sentinels&' K assert&start_sentinel == 6+A0+_PA"I.'; assert&end_sentinel == !N7_PA"I.'; L // ==== pri$ate: // +his :ust #e the last declaration const long unsigned int end_sentinel; L; !his class de)ines t"o constants "hich are declared at each end o) the class !he ter# /constant3 is slightly incorrect !hey are really varia,les "hich are initialiFed "hen the class is created and can not ,e #odi)ied during the li)eti#e o) the class @ut they can ,e over"ritten i) so#e ,uggy code over)lo"s an array, uses a ,ad #e#ory pointer, or does so#ething else craFy ;) that happens the ne&t call to chec8_sentinels "ill cause an assertion )ailure crashing the progra#

Page A0

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

So "hat "e are actually doing is reducing a di))icult to solve pro,le# 0rando# over"rites o) #e#ory cause rando# results2 to one that5s easier to solve 0as soon as the #e#ory goes ,ad, the progra# crashes2 !his type o) code helped #e locate a rather unusual pro,le# "ith so#e C code "hat had ,een upgraded to C++ ;n this case the )irst call to chec8_sentinels crashed the progra# %nalyFing the progra# ; discovered that the pro,le# "as caused so#e"here ,et"een "hen the constructor "as called and the )irst sentential veri)ication call So ; put a ,reakpoint in the constructor and "as planning to single step through the code until ; )ound the pro,le# !he progra# crashed ,e)ore the constructor "as called So ; "as le)t "ith a puFFle /Ho" can a progra# call a #e#,er )unction ,e)ore it calls the constructorS3 !he ans"er "as surprisingly si#ple !he class "as ,eing created "ith

:alloc ; told you it "as once C !urns out that it "as not =uite )ully ported )ro# C to C++ -eplacing :alloc "ith new solved the pro,le# Hack (1: Sol1e Memor! 'ro0lems "ith 1al*rind
The Problems: @ad pointers, "riting o) the end o) allocated #e#ory, #e#ory leaks C++ gives you lots o) )le&i,ility "hen it co#es to #e#ory #anage#ent (ou are allo"ed to allocate and deallocate #e#ory and directly #anipulate pointers 'le&i,ility co#es "ith a cost @ecause the language allo"s you to allocate #e#ory, you can scre" up the allocations Si#ilarly you can scre" up the deallocation and use o) pointers Since there are no ,uiltCin sa)ety checks in C++ "hat do you do to protect your codeS The Hack* .se valgrind !he valgrind progra# runs your progra# in a sort o) virtual #achine 8e#ory accesses undergo e&tra checking !hat #akes it possi,le to detect certain types o) pointer errors !hese include* 1 .sing )reed #e#ory 2 6riting past the end o) a allocated ,lock

Page A1

Copyright 2008, Steve Oualline

C++ Hackers Guide 4 6riting past the ,eginning o) an allocated ,lock > 8e#ory $eaks $et5s take a look at a s#all e&a#ple* ( * ? B F E D A ] (; (( Jinclude Ciostrea:H int :ain&' K int* ptr = new intT(;U; int* ptr_# = new intT(;U; *&ptrM((' = F; ptr_# = N2 ; exit&;'; L

Steve Oualline

ote: (ou #ay have noticed that "e violated our o"n sa)ety rules ,y not putting asse(t state#ents ,e)ore each pointer access @ut the purpose o) this code is to cause pro,le#s, not catch the#, so "e disa,led the sa)ety5s 6hat are the pro,le#s "ith this codeS On line 8 "e access ele#ent 11 o) a 10 ele#ent array On line 7 "e Fero out the only pointer to the #e#ory "e allocated in line A thus causing a #e#ory leak $et5s look at "hat valgrind does "hen this progra# is run
? *al"rind --lea@-c ec@=+!ll .9'ad2mem ==31)%%== Aemc ec@, a memory error detector. ==31)%%== 1o#yri" t 416 2002-200(, and BN- BPL7d, 'y <!lian Ceward et al. ==31)%%== -sin" Li'D0E re* 1(%F, a li'rary +or dynamic 'inary translation. ==31)%%== 1o#yri" t 416 2004-200(, and BN- BPL7d, 'y G#en;or@s LLP. ==31)%%== -sin" *al"rind-3.2.1, a dynamic 'inary instr!mentation +ramewor@. ==31)%%== 1o#yri" t 416 2000-200(, and BN- BPL7d, 'y <!lian Ceward et al. ==31)%%== ,or more details, rer!n wit : -* ==31)%%== ==31)%%== :n*alid write o+ siHe 4 ==31)%%== at 08F04F)12: main 4'ad2mem.c##:F6 ==31)%%== Iddress 0842%30%4 is 4 'ytes a+ter a 'loc@ o+ siHe 40 alloc7d ==31)%%== at 08401JD%%: o#erator new=>4!nsi"ned6 4*"2re#lace2malloc.c:1J%6 ==31)%%== 'y 08F04F(,%: main 4'ad2mem.c##:%6 ==31)%%== ==31)%%== 0&&G& C-AAI&K: 1 errors +rom 1 conte8ts 4s!##ressed: 21 +rom 16 ==31)%%== malloc9+ree: in !se at e8it: F0 'ytes in 2 'loc@s. ==31)%%== malloc9+ree: 2 allocs, 0 +rees, F0 'ytes allocated. ==31)%%== ,or co!nts o+ detected errors, rer!n wit : -* ==31)%%== searc in" +or #ointers to 2 not-+reed 'loc@s. ==31)%%== c ec@ed 104,)J( 'ytes. ==31)%%==

Page A2

Copyright 2008, Steve Oualline

C++ Hackers Guide


==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%== ==31)%%==

Steve Oualline

40 'ytes in 1 'loc@s are de+initely lost in loss record 1 o+ 2 at 08401JD%%: o#erator new=>4!nsi"ned6 4*"2re#lace2malloc.c:1J%6 'y 08F04F)0%: main 4'ad2mem.c##:(6 L0IL C-AAI&K: de+initely lost: 40 'ytes in 1 'loc@s. #ossi'ly lost: 0 'ytes in 0 'loc@s. still reac a'le: 40 'ytes in 1 'loc@s. s!##ressed: 0 'ytes in 0 'loc@s. &eac a'le 'loc@s 4t ose to w ic a #ointer was +o!nd6 are not s own. To see t em, rer!n wit : --s ow-reac a'le=yes

%)ter so#e chatter, the progra# catches the )irst thing the tool notices is the "rite to an illegal #e#ory location*
==31)%%== :n*alid write o+ siHe 4 ==31)%%== at 08F04F)12: main 4'ad2mem.c##:F6 ==31)%%== Iddress 0842%30%4 is 4 'ytes a+ter a 'loc@ o+ siHe 40 alloc7d ==31)%%== at 08401JD%%: o#erator new=>4!nsi"ned6 4*"2re#lace2malloc.c:1J%6 ==31)%%== 'y 08F04F(,%: main 4'ad2mem.c##:%6

%)ter the progra# )inishes, valgrind checks the heap to see i) any #e#ory "as lost ;n this case it )ind that "e allocated so#e #e#ory at line A and lost it
==31)%%== 40 'ytes in 1 'loc@s are de+initely lost in loss record 1 o+ 2 ==31)%%== at 08401JD%%: o#erator new=>4!nsi"ned6 4*"2re#lace2malloc.c:1J%6 ==31)%%== 'y 08F04F)0%: main 4'ad2mem.c##:(6

!he tool is s#art ;t didn5t report the #e#ory "e allocated on line ? as lost even through "e allocated it and never )reed it !hat5s ,ecause at the ti#e the progra# e&ited there "as a pointer to this ,lock o) #e#ory ;n other "ords so#eone "as using it at e&it ti#e, so it "as not lost !he valgrind tool is not per)ect can not )ind pro,le#s "ith local or glo,al arrays, only allocated #e#ory @ut still it does a very good Ko, o) )inding a large nu#,er o) di))icult to locate pro,le#s

Hack (2: #indin* Uninitiali<ed ;aria0les


The Problem: (our progra# does strange things at rando# ti#es (ou suspect an initialiFed varia,le

Page A4

Copyright 2008, Steve Oualline

C++ Hackers Guide Consider the )ollo"ing e&a#ple* ( * ? B F E D A ] (; (( (* Jinclude Ciostrea:H static $oid print_state&' K int state;

Steve Oualline

i, &state' K std::cout CC 96tate alpha9 CC std::endl; L else K std::cout CC 96tate #eta9 CC std::endl; L L

%t line B "e use the value o) state to decide i) "e do the alpha or ,eta parts !here5s Kust one pro,le#, "e never ,other to give state a value So "hich state "ill ,e e&ecutedS !hat depends on "hat the previous )unction le)t on the stack ;n other "ords, state "ill ,e set to so#e rando# nu#,er Ho" do you detect such thingsS ;t5s di))icult using the de,ugger ;) you print the value o) state and get 481204>7, ho" do you kno" i) that is correct or incorrectS The Hack: valgrind to the rescue !he valgrind progra# also checks to see i) you use any uninitialiFed data ;t5s actually rather clever a,out this ;) you assign one uninitialiFed varia,le to another, it "on5t co#plain 0!his actually happens a lot "hen doing :e:cp% and other si#ilar operations 2 @ut i) you try to use uninitialiFed data to #ake a decision 0inside an if state#ent )or e&a#ple2 it "ill co#plain loudly 'or e&a#ple "hen "e run the previous progra# under valgrind "e get*
... c atter ... ==2(4FF== 1onditional M!m# or mo*e de#ends on !ninitialised *al!e4s6 ==2(4FF== at 08F04F)DI: #rint2state46 4!init.c##:)6 ==2(4FF== 'y 08F04FF41: main 4!init.c##:1(6 Ctate al# a ... more c atter ...

!his clearly sho"s us that line B has a pro,le# "ith uninitialiFed data

Page A>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 23: ;al*rind 'ron%nciation


The Problem: Ho" do you pronounce /Ealgrind3S The Hack: 6e hackers 6e don5t care ho" it5s pronounced as long as it "orks

Hack (3: Locatin* 'ointer pro0lems Electric#ence


The Problem* (ou need to )ind #e#ory allocation errors The Hack: 9on5t use :lectric'ence it5s stagnant :ven its successor, 9.8% is o,solete .se valgrind instead

Hack ((: Dealin* "ith Comple& #%nction and 'ointer Declarations


The Problem: (ou need to create a pointer to a )unction "hich takes a integer argu#ent and returns an array o) pointers to )unctions "hich take one argu#ent, a string, and return an integer 6he"N !hat5s a speci)ication you have to read at least three ti#es to )igure out that you can5t understand it Ho" do you deal "ith such co#ple&ity The Hack* -edesign the code so you don5t need this type o) )unction $et5s assu#e that the "orld is insane and "e can5t do that !hen "e need to ,reak the declaration do"n into pieces and use lots o) typedef state#ents to #ake things si#pler Hacking does not #ean that you do the #ost co#ple& thing in the #ost co#ple& "ay % good hacker does the #ost co#ple& thing in a si#ple "ay $et5s start ,y parsing the sentence and look )or the ,otto# #ost ele#ent in this speci)ication change !he ,ase ite# is a )unction "hich takes one argu#ent, a string, and returns an integer ;t5s easier said in C++* t%pede, int #ase_,unction&const char* const arg'; Go" "e are going to return an array o) pointers to this type o) )unction 'irst "e de)ine a type )or the pointer* t%pede, #ase_,unction* #ase_,unction_ptr; Ge&t "e de)ine an array o) pointers* t%pede, #ase_,unction_ptr #ase_arra%TU;

Page A?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Go" "e need a )unction "hich returns a pointer to this array* t%pede, #ase_arra%* #ig_,un&int $alue'; 'inally "e declare a pointer to this ite#* #ig_,un* the_pointer; Go" you #ay have noticed that "e used )our typedef state#ents to de)ine this one pointer 6e could have done this in one state#ent @ut the goal o) this hack "as to de)ine the pointer "ith a #ini#u# o) e))ort, not a #ini#u# o) code Clarity is one =uality highly valued ,y good hackers and ,y ,reaking do"n this pro,le# into #ultiple, s#all typedef state#ent "e can use #any s#all clear state#ents in place o) one large co#ple& and i#possi,le to understand C++ declaration !he )ull code 0including co##ents2 )ollo"s* // +%pe de,inition ,or a ,unction which ta8es // a character argu:ent and returns an integer t%pede, int #ase_,unction&const char* const arg'; // 3ointer to a #ase ,unction t%pede, #ase_,unction* #ase_,unction_ptr; // An arra% o, pointers to our #ase ,unction t%pede, #ase_,unction_ptr #ase_arra%TU; // 5unction which returns an arra% o, ,unction // pointers t%pede, #ase_arra%* #ig_,un&int $alue'; // 5inall% a pointer to the thing we wished // to point to #ig_,un* the_pointer; %s hackers "e are e&pected to think out o) the ,o& and look ,eyond the initial pro,le# One =uestion that "e haven5t dealt "ith is /6hy "ould you ever need such a pointerS3 ;n the real "orld, a good hacker "ould not design a ,etter "ay to declare the pointer, he "ould design code so that a pointer like this "as never needed in the )irst place :li#ination o) needless co#ple&ity is one o) the attri,utes o) a truly great hacker

Page AA

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter !: "ile Hacks


Hacking is not Kust a,out "riting progra#s Progra#s trans)or# and process data @ut the data itsel) can also ,e su,Kect to hacking 9esigning a good )ile )or#at is one key part o) creating a good progra# !he )iles should ,e easy to use, ro,ust, and e&panda,le !he hacks contained in this chapter are designed to help you achieve all these goals !he key to good )ile design is to #ake things as si#ple as possi,le, ,ut no si#pler, and as )le&i,le as possi,le "ithout getting silly ;t also helps to ,e as transparent as possi,le so any pro,le#s "ith the )ile can easily ,e located %s hackers "e "ant our progra#s used as #uch as possi,le !his #eans designing )ile )or#ats that are so good that people "ant to use the# T8$ is one e&a#ple o) a si#ple, yet ro,ust )ile )or#at Si#ple enough so that anyone can read it 0sort o)2 yet co#ple& enough so you can speci)y Kust a,out anything Good progra##er create good )iles Good hackers create great ones

Hack (+: Create )e&t #iles Instead o, -inar! 8nes Whene1er #easi0le
The Problem: (ou need save the con)iguration data 0or other data2 )ro# your progra# 9o you use a ,inary )ile or and te&t )ileS The Hack: .se te&t ;t al#ost al"ays #ake things easier .G;T is an e&cellent e&a#ple o) hacker design One o) the key design )eatures that #ake the syste# "ork as "ell as it does is that al#ost all the con)iguration )iles are te&t !here are nu#erous advantages to te&t )iles !he )irst is that they are hu#an reada,le 6hen your progra# "rite a te&t )ile, the contents o) the )ile can ,e e&a#ined ,y si#pling looking at it (ou don5t have to create so#e )ancy data du#per to look at the )ile !his illustrates one o) the #aKor advantages o) te&t )iles* transparency (ou can see "hat5s going on in a te&t )ile %lso you change change it easily using an editor !his #eans that i) you progra# needs a con)iguration )ile and that )ile is in te&t )or#at, then a te&t editor can ,e used to edit the con)iguration 0; didn5t say it "ould ,e easy or pretty, ,ut it can ,e done 2

Page AB

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

%lso i) the con)iguration in)or#ation te&t ,ased, other people can easily "rite tools "hich edit the con)iguration )ile On $inu& you5ll )ind literally hundreds o) progra#s "hich con)igure net"ork settings !hat5s ,ecause the net"ork con)iguration is stored in a te&t )ile and easily accessi,le to everyone %gain, one o) your goals as a hacker is to #ake things a si#ple and easy to play "ith as possi,le !e&t )iles let you do this @inary )iles are only use)ul "hen you are processing huge a#ount o) data 0video, graphics, data,ases, etc 2 6hen you are dealing "ith 100,000,000 records or #ore, then the overhead associated "ith te&t )iles can #ake your progra# slo" do"n tre#endously ;n that case ,inary )iles are ,etter @ut )or si#ple things like con)iguration )iles, settings )iles, and ,asic data te&t )iles are ,est Per)or#ance is not an issue 6ho cares i) it takes 0 004 seconds to start your progra# instead o) 0 001 @ut people do care a,out clarity, correctness, and interopera,ility and that "here te&t )iles are ,est Ho. ot to *esign a Configuration 'ystem

!he conse=uences o) a ,ad design are "orth study too $et5s look at one very co##on syste# )or storing con)iguration settings 'irst o) all, all the con)iguration in)or#ation )or every progra# on the entire syste# is stored in one location !here are several pro,le#s "ith this* 1 % single "ild progra# can accidentally totally destroy all the settings 0!he solution to this pro,le#* 9on5t redesign, the con)iguration syste#, provide a ela,orate ,ackup syste# so "hen destruction does occur you can recover Q sort o) 2 2 8ake the )ile ,inary so no one can easily read it e&cept "ith an %P; that you supply 4 <eep the )or#at secret and only the user edit the con)iguration data using the tool you provide @y keeping things secret you a,solutely prevent anyone )ro# "riting a ,etter progra# > @ecause all settings are stored in one location, you5ve #ade it i#possi,le to create several con)iguration )iles to ,e used )or di))erent situations (ou li#it everyone on the #achine to one con)iguration period Page A8 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

? 'inally ,ecause con)iguration data can only ,e stored on the local #achine in a single location, con)iguration sharing is i#possi,le !he syste# ;5ve ,een descri,ing is the 8icroso)t 6indo"s -egistry ;t is )ascinating )ro# a design point o) vie" ,ecause it gives good designers so#e #any opportunities to ask /6hat "ere they thinking "hen they did thisS3

Hack (.: Use Ma*ic Strin*s to Identi,! #ile )!pes


The Problem: (our progra# needs the user to speci)y a con)iguration )ile and a settings )iles @ut the users can easily get the t"o #i&ed up causing havoc "ith your progra# The Hack: .se a #agic string Si#ply use a kno"n string at the ,eginning o) each type o) )ile to identi)y it 'or e&a#ple, a typical con)iguration )ile #ight look like* J +"3 .on,iguration 5ile sol$e = true ,eatures = no$ice ==== !he key things to notice a,out the #agic string are that it identi)ies the progra# it ,elongs to as "ell as the )ile type So )iles that ,egin "ith this string and only )iles that ,egin "ith this string are con)iguration )iles !hus you prevent errors ,y )orcing the user to give you a con)iguration )ile "hen a con)iguration )ile is needed

Hack (/: Use Ma*ic =%m0ers ,or -inar! #iles


The Problem: Our progra# uses ,inary )iles as input Ho" can "e ,e sure "e get the right ,inary )ilesS The Hack: Put a #agic nu#,er at the ,eginning o) the )ile Go" the =uestion is ho" do you decide on the #agic nu#,er !he short ans"er is that you #ake it up

Page A7

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!here are #any di))erent "ays o) doing this !he #ethod ; pre)er is to think up a "ord that descri,es the progra# ;5# creating 'or e&a#ple /H%C<S3 !aking the )irst > letters and seeing "hat the %SC;; nu#,ers )or the# ; get* H % C < >8 >1 >4 >@

Putting these together gives us the nu#,er ;xBAB(B?B1 !he pro,le# "ith this nu#,er is that ,ecause it is )our %SC;; characters and the )ile can easily ,e con)used "ith a te&t )ile So "e add ;xA;A;A;A; to the nu#,er giving us a ;x.A.(.?.1 !he result is our #agic nu#,er* // +he :agic nu:#er at the #eginning o, each hac8 ,ile const long unsigned int IA.4_PA"I. = ;x.A.(.?.1 ; !he )inal step is to "rite out a )ile "ith our ne" #agic nu#,er in it and see i) the $inu& )ile co##and can identi)y it as an e&isting nu#,er 0ML 1iles !he T8$ )ile )or#at has ,een designed to solve a great #any o) the pro,le#s "ith )ile )or#ats ;t5s structured so that you can design =uite co#ple& things, it hu#an reada,le 0sort o)2, and you can easily validate it

Hack (2: 7%tomatic -!te 8rderin* )hro%*h Ma*ic =%m0ers


The Problem: @inary )iles are not porta,le 'iles "ritten on a Sparc #achine can not ,e read on a &8A #achine The Hack: .se the #agic nu#,er to detect )ile "ritten "ith a di))erent ,yte order and correct it

Page B0

Copyright 2008, Steve Oualline

C++ Hackers Guide 'or e&a#ple*

Steve Oualline

// +he :agic nu:#er at the #eginning o, each hac8 ,ile const long unsigned int IA.4_PA"I. = ;x.A.(.?.1 ; // +he :agic nu:#er on a :achine with a di,,erent #%te // order const long unsigned int IA.4_PA"I._6-I+.I = ;x.1.?.(.A ; // ===== long unsigned int :agic; in_,ile=read&>:agic) si<eo,&:agic''; i, &:agic == IA.4_PA"I.' K process_,ile&'; L else i, &:agic == IA.4_PA"I._6-I+.I' K process_,ile_a,ter_,lipping_#%tes&'; L else K throw&,ile_t%pe_exception& 5ile is not a hac8 data ,ile ''; L !he idea is si#ple, )irst check to see i) "e have a nor#al )ile and process it i, &:agic == IA.4_PA"I.' K process_,ile&'; 6e notice that a nor#al #agic nu#,er is ;x.A.(.?.1 On a #achine "ith a di))erent ,yte order the #agic nu#,er is ;x.1.?.(.A ;) "e detect a #agic nu#,er that #atches this value, "e kno" "e have a ,yte )lipped )ile and process it* const long unsigned int IA.4_PA"I._6-I+.I = ;x.1.?.(.A ; // ==== L else i, &:agic == IA.4_PA"I._6-I+.I' K process_,ile_a,ter_,lipping_#%tes&'; ote* %lthough this syste# "orks, you do have to #aintain t"o version o) the )ile reading progra# !his can ,e a signi)icant #aintaina,le and risk pro,le# (ou #ay "ant to consider using the ne&t hack instead

Hack (3: Writin* 'orta0le -inar! #iles


The Problem: (ou need to create and read ,inary )iles "hich can ,e used on #ultiple #achines The Hack: %l"ays "rite out the data using /Get"ork @yte Order3 Page B1 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;n order to #ake data trans#ission plat)or# independent a standard ,yte order called /Get"ork @yte Order3 "as created % nu#,er o) )unctions "ere added to the C li,rary to convert ite#s to and )ro# net"ork ,yte order !he include*

htonl htons ntohl ntohs

1unction

Convert Convert Convert Convert

a a a a

Meaning long in host )or#at to net"ork )or#at short in host )or#at to net"ork )or#at long in net"ork )or#at to host )or#at long in net"ork )or#at to host )or#at

$et5s see ho" this #ight ,e used "hen "riting a )ile* // +he :agic nu:#er at the #eginning o, each hac8 ,ile const long unsigned int IA.4_PA"I. = ;x.A.(.?.1 ; short int ite:_count = (F; // Nu:#er o, ite:s in the ,ile short int ,ield_length = ((; // ength o, next ,ield // === long unsigned int :agic = htonl&IA.4_PA"I.'; out_,ile=write&>:agic) si<eo,&:agic''; short int write_ite:_count = htons&ite:_count'; out_,ile=write&>write_ite:_count) si<eo,&write_ite:_count''; short int write_,ield_length = htons&,ield_length'; out_,ile=write&>write_,ield_length) si<eo,&write_,ield_length''; Si#ilar code is used on the read side to #ake things porta,le

Hack +5: Make :o% -inar! #iles E&tensi0le


The Problem: People keep "anting to e&tend progra#s ,y adding #ore )eatures ;) the progra# deals "ith ,inary )iles the )ile )or#at #ust acco##odate this The Hack: 6hen designing )iles leave roo# )or e&pansion .se a )ile )or#at "hich includes a record siFe in each record Here5s a si#ple )ile )or#at speci)ication* 1 -ecord type 0> ,yte integer2 Page B2 Copyright 2008, Steve Oualline

C++ Hackers Guide 2 -ecord length 0> ,yte integer2 4 -ecord data 0length Q 8 ,ytes o) data2

Steve Oualline

!his is a deceptively si#ple )or#at %lthough si#ple, it leaves lots o) roo# )or e&pansion $et5s start "ith the code used to read the records ;t #ust read the )irst 8 ,ytes, get the length, then read the rest o) the data !he entire record is then returned to the reader )or processor Eery si#ple % good hack %ll the progra# has to do is to look a the record type to deter#ine "hat type o) data is in the record !hen it can process the record Go" "hat happens "hen "e need to e&pand and enhance our data strea# %ll "e have to do is to add a ne" record type !he reader doesn5t have to ,e changed ;t can still process the record ,ecause it doesn5t have to kno" the type %ll "e have to do is add a ne" record handler to the #ain progra# 'or e&a#ple* struct record K int t%pe; // 0ecord t%pe int length; // ength o, record uintA dataT;U; // 7ata &$aria#le length'; L; // ==== switch &record_$ar=t%pe' K case 0!._6+A0+: do_start&record_$ar'; #rea8; case 0!._6+/3: do_stop&record_$ar'; #rea8; case 0!._3A26!: do_pause&record_$ar'; #rea8; de,ault: std::cout CC -A0NIN": 2n8nown record t%pe CC record_$ar=t%pe CC Ignored CC std::endl; #rea8; L 6ith code like this it5s easy to add a handler )or a ne" record Ge" handlers easily )it into the sche#a Page B4 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

%lso this code "ill "ork )or ,oth past and )uture version o) the )ile ;t "orks "ith )uture versions ,ecause it skips records it does not kno" a,out So i) "e add a ne" record type such as ,-._/0I1, the progra# "ill still run ;t "on5t process records it doesn5t kno" a,out, ,ut it "on5t crash either !his ,uiltCin resilience is the hall#ark o) a really good hack

Hack +1: Use ma*ic n%m0ers to protect 0inar! ,ile records


The Problem: 'iles can ,eco#e corrupt Ho" do "e protect ourselves against that The Hack: Put #agic nu#,ers at the ,eginning and end o) each record 'or e&a#ple* struct record_start K uint?* :agic_start; uint?* t%pe; uint?* si<e; L; struct record_end K unit?* :agic_end; L So#e"here in the recording code "e have the state#ents* i, &record_strea:=start=:agic_start R= 6+A0+_PA"I.' throw&,ile_corruption&6tarting :agic nu:#er wrong'; // ==== i, &record_strea:=end=:agic_end R= !N7_PA"I.' throw&,ile_corruption&!nding :agic nu:#er wrong'; Go" "hen anyone #onkeys "ith the )ile "e notice ;t should ,e pointed out that this protects against al#ost all si#ple data corruption caused ,y hard"are errors or progra# ,ugs %lso it only protects the ends o) the data ;) so#eone #esses up the #iddle it "on5t ,e spotted ;) you "ant to spot that you5ll need to include a checksu# o) so#e sort in the data itsel) @ut that5s a level o) paranoia that5s rarely needed

Page B>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his hack has proved use)ul to #ysel) in a nu#,er o) occasions !he )irst "as a )ile syste# pro,le# ;t see#ed that "hen the co#puter "as shutdo"n and there "ere )iles ,eing "ritten to the disk, the operating syste# "ould pad the un"ritten sectors "ith ,locks containing all Feros 'ortunately the #agic nu#,ers "ere there and the progra# realiFed that it had read so#ething that "as hal) a good record and hal) so#ething else and discarded the data !he other pro,le# caught ,y this syste# "as a really nasty data corruption ,ug !he pro,le# "as eventually traced to code in an entirely di))erent #odule "hich sent out :C8ail alerts "hen an error condition occurred Here5s the code $et5s see i) you can spot the pro,le#* pid_t child_pid = ,or8&'; i, &child_pid == ;' K // -e are the child s%ste:&send_e:ail_alert'; exit&;'; L ;) you didn5t spot the ,ug ; can understand ;t took #e a,out a "eek o) testing to pinpoint this code and locate the pro,le# !he pro,le# is very hard to see %)ter all this entire #odule shares no code "ith the record "riting #odule ;n particular the output )ile handle does not e&ist at all outside the record "riter %lso the code in =uestion does no ;1O ;t doesn5t even #anipulate #e#ory so it couldn5t ,e #e#ory corruption So "hat is going onS !here are t"o parts to this pro,le# !he )irst is the call* pid_t child_pid = ,or8&'; !his creates a duplicate o) the #ain process %ll )ile handles are no" shared ,et"een the t"o processes So "here ,e)ore there "as one process "ith the output )ile open, no" there are t"o !he ,or8 call also duplicates the #e#ory o) the parent process !his includes all the ;1O ,u))ers )or all the )iles !his includes the output )ile Ge&t "e co#e to the line* exit&;'; %ll this does is e&it the progra#, rightS Got e&actly $et5s take a look at the docu#entation )or this )unction* Page B? Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

+he exit&' ,unction causes nor:al progra: ter:ination and the the $alue o, status > ;?DD is returned to the parent &see wait&*''= All ,unctions registered with atexit&' and on_exit&' are called in the re$erse order o, their registration) and all open streams are flushed and closed= 5iles created #% t:p,ile&' are re:o$ed=
!he e2it )unction actually does =uite a lot ;n particular it )lushes the "rite ,u))ers )or any )iles open )or "riting Since "e inherited a set o) open )iles and their ,u))ers )ro# the parent, they "ill ,e )lushed !hus this call "rites so#e data to the )ile !he #ain progra# "ill also "rite so#e data to the )ile "hen it5s ,u))ers get )ull Since these t"o "rites are not coordinated the data is corrupted !his "as a nasty pro,le# to )ind @ut the )act that the code "as "ritten "ith record protection in it, catching the pro,le# "as #uch easier :arly on it "as o,vious that turning on alerts cause the progra# to co#plain a,out record corruption !he only hard part "as looking at the code and trying to )igure out the pro,le# 6hat #ade this nasty is that the logs "ere getting corrupted, ,ut only i) alerts "ere turned on @ut these #odules had nothing in co##on !he shared no )unctions, logic, or #e#ory ;t took =uite so#e ti#e to )ind out that the pro,le# "as that they did share so#ething* ;1O ,u))ers, ,ut that sharing "as very "ell hidden

Hack +2:

no" When to Use De&it

The Problem: (ou are )orking o)) a process and do so#e "ork and then e&it, "ithout doing anything to the ;1O ,u))ers in the process (ou can5t use the e2it )unction ,ecause o) the pro,le#s descri,ed in Hack ?1 The Hack: .se _e2it !he _e2it )unction stops your progra# !hat5s all it does, stop the progra# ;t does not pass go, it does not collect R200 @ut #ore i#portantly it does not )lush any ;1O ,u))ers %ll that happens "hen you call _e2it is that your process goes a"ay

Page BA

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his is very use)ul "hen you5ve )orked o) a process that has done it5s "ork and needs to stop -e#e#,er e2it )lushes things and can cause all sorts o) trou,le "ith shared )iles !he _e2it call avoids this pro,le#

Page BB

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter #: $ebugging Hacks


; have "ritten t"o progra#s "hich had no ,ugs One "as three #achine instructions long and the other "as )our %ll the others had ,ugs !he "riting o) a progra# takes only a short ti#e 9e,ugging goes on )orever !he de,ugging hacks presented here are designed to #ake de,ugging )aster and #ore e))icient

Hack +3: Mark temporar! de0%**in* messa*es "ith a special set o, charactersE
The Problem: 9e,ugging ,y adding print state#ents is still a very po"er)ul de,ugging techni=ue @ut ho" do you identi)y print state#ents designed to output in)or#ation )or a speci)ic pro,le# vs the print state#ents that should ,e there The Hack* @egin all te#porary de,ugging output "ith the characters /DD3 'or e&a#ple* i = ,ind_index&'; std::cout CC JJ ,ind_index returned CC i CC std::endl; !he /DD3 serves several purposes 'irst, it identi)ies the state#ent as a te#porary de,ug state#ent Ge&t "hen you do )ind the pro,le# it5s easy to re#ove the# %ll you have to do is go through and )ind each line containing a /DD3 and delete it

Hack +(: Use the Editor to 7nal!<e Lo* 8%tp%t


The Problem: 6hen you turn on ver,ose logging you get ?0,000 lines scrolling past #y screen and ; can5t )ind "hat ;5# looking )or The Hack: Save the log output to a )ile and use a te&t editor to ,ro"se the output !he pro,le# "ith log )iles is that they give you too little in)or#ation or too #uch !oo little is easily dealt "ith Q all you have to do is turn up the ver,osity level until you get too #uch or put in DD lines 0See previous hack 2 9ealing "ith too #uch is another pro,le# Ho" do you )ind that nugget o) in)or#ation "hich tells you Kust "ant you need to kno"S

Page B8

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

6ell on #ost syste#s there5s a tool designed )or the searching and #anipulation o) large te&t )iles ;t5s called your syste# editor $et5s see ho" this "orks in action 'irst let5s suppose you5ve done an e&haustive test o) your syste# and logged the results Out o) ?,000 tests, three )ail "ith an error Si#ple start up your editor and search )or the string /:--O-3 (ou5ll locate the line o) the )irst error 6ant to see "hat happened Kust ,e)ore the error, scroll up and take a look !he editor not only lets you look at the data ,ut annotate it as "ell (ou can add co##ents and annotations to the log as you )igure out "hat is going on %nd unlike paper notes, edits in the )ile can ,e inserted into an :C8ail in case you have to use the ;nternet )or help $og )iles are a great source o) in)or#ation and the te&t editor is a great "ay to e&ploit this in)or#ation 0See Hack 12B )or in)or#ation on ho" to Ei# to e&a#ine log )iles 2

Hack ++: #le&i0le Lo**in*


The Problem: 6hen your dealing "ith s#all progra#s it5s O< to log everything ;) you have a larger progra# you need to ,e #ore selective The Hack: .se letter ,ased logging selection 6e "ish to create a co##and line para#eter N$<letters> "hich "ill ena,le de,ugging )or only those sections speci)ied ,y ClettersH 'or e&a#ple a typical set o) letters #ight ,e* # d ) r & $og #e#ory allocation and )rees $og dictionary entries Print )unction de)initions Print regular e&pression de,ugging in)or#ation 9isplay calls to the e&ecute )unction and so on !his syste# is surprising easy to i#ple#ent 'irst "e de)ine an array to hold our de,ug options* Page B7 Copyright 2008, Steve Oualline

C++ Hackers Guide static #ool $er#ose_lettersT*FEU = K;L;

Steve Oualline

Ge&t "e create a loop to process the co##and line argu#ents ;n this e&a#ple "e5re are using the GG. getopt )unction to scan the argu#ents 6e use the argu#ent speci)ication $:: to indicate the only option is N$ and that it can ,e )ollo"ed ,y options para#eters 0!his is indicated ,y the /**3 a)ter the /v3 2 while &(' K int opt = getopt&argc) arg$) 9$::9'; Go" "e process the options !here are t"o possi,le "ays o) speci)ying Cv !he )irst is Kust Cv alone ;n that case "e turn on all de,ugging in)or#ation "ith the line* :e:set&$er#ose_letters) N() si<eo,&$er#ose_letters''; @ut i) the options has argu#ents then "e only set the letters o) the given options* ,or &unsigned int i = ;; optargTiU R= '@;'; MMi' $er#ose_lettersT static_castCintH&optargTiU'U = true; Putting it all together "e get the )ollo"ing code )or parsing the ver,ose option* switch &opt' K case '$': i, &optarg == ;' K :e:set&$er#ose_letters) N() si<eo,&$er#ose_letters''; L else K ,or &unsigned int i = ;; optargTiU R= '@;'; MMi' $er#ose_lettersTstatic_castCintH&optargTiU'U = true; L #rea8; // === process other options Checking to see need to issue a de,ugging #essage is si#ple 'or e&a#ple to check )or :alloc logging "e use the code* i, &$er#ose_lettersT':'U' K std::cerr CC 7oing a :alloc o, CC si<e CC #%tes; L ptr = :alloc&si<e'; Page 80 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;n actual practice "e "ould de)ine a constant )or ':', ,ut )or this short e&a#ple "e5ll e&cuse the ,ad progra##ing practice !his "ay o) speci)ying "hat to log allo"s us to use all the lo"er case letters, all the upper case letters, and all the digits to select "hat to log %nd i) that5s not enough there are lost o) punctuation characters "e can use as "ell 0%nd i) that5s not enough, your progra# is pro,a,ly too ,ig to ever ,e de,ugged any"ay 2 !"o attri,utes #ake this a good hack 'irst it is si#ple Second it is e&tre#ely )le&i,le ;n other "ords it a si#ple solution to a co#ple& pro,le#, and si#ple solutions are al"ays good

Hack +.: )%rn De0%**in* 8n and 8,, With a Si*nal


The Problem: (ou "ant de,ugging output so#e o) the ti#e ,ut not all o) the ti#e The Hack* .se a signal to turn on and o)) de,ugging !he )irst step is to de)ine a signal hander that toggles the de,ug )lag* static $oid toggle_de#ug&int' K de#ug = R de#ug; L Ge&t "e connect it to a signal, in this case /I34/,1 signal&6I"260() toggle_de#ug'; Go" all "e have to do is #ake the logging conditional on the de#ug )lag static $oid log_:sg&const char* const :sg' K i, &de#ug' K std::cout CC :sg CC std::endl; L L Go" all "e have to do to turn on de,ugging is use the co##and* ^ 5ill -4/,1 pid !urning it o)) is the sa#e thing !his hack is use)ul "hen you #ust turn on de,ugging output at a speci)ic ti#e Gor#ally it5s easier to Kust turn it on "hen you )irst start the progra# and then leave it on Page 81 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut so#eti#es you need to instru#ent the #ain loop o) a progra# that #ysteriously hangs a)ter )our days o) operations Since you don5t have a couple o) tera,ytes o) )ree disk space )or the log )iles, you need to turn on de,ugging a)ter the progra# hangs in order to )ind out "hat is going on that is #aking things nuts !hat5s "here this hack is #ost use)ul

Hack +/: Use a Si*nal #ile to )%rn 8n and 8,, De0%**in*


The Problem: (ou need to turn on and o)) de,ugging and signals are Kust not practical The Hack: .se a special )ile to trigger de,ugging 'or e&a#ple* static $oid log_:sg&const char* const :sg' K i, &access&/t:p/prog=de#ug=on) 5_/4' R= ;' K std::cout CC :sg CC std::endl; L L

Go" all you have to do to turn on de,ugging is to create the )ile 1t#p1prog de,ug on !o turn it o)) si#ply re#ove the )ile !his hack should ,e only used "hen you a,solutely need to turn de,ugging on and o)) "hile the progra# is running and you can use signals 0Hack ?A2 !he access syste# call is e&pensive and "ill slo" your progra# do"n i) used )re=uently So although this hack is use)ul, ,e a"are o) its li#itations

Hack %&: Starting the $ebugger 'utomaticall

(pon )rror

The Problem: (our progra# has detected an internal pro,le# that needs de,ugging @ut the progra# is not ,eing de,ugged Ho" do you let the progra##er at the pro,le#S The Hack: 9e)ine a )unction "hich starts the de,ugger on a running progra# ote: !he )ollo"ing code is $inu& speci)ic ;) you are running on a .G;T like syste# it should ,e easy to port it to that syste# ;) you are running 8icroso)t 6indo"s, you5re on your o"n

Page 82

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he ,asic idea o) the progra# is that "hen a de#ug_:e )unction call occurs that the progra# should start the de,ug 0gd,2 and attach it to the running process Sounds si#ple, ,ut there are a )e" details to "ork out 'irst let5s see "hat "e need to tell gd, start the de,ugging process !he initial gd, co##ands are* 1 attach Cpid> de,ugged Q %ttach the de,ugger to the progra# ,eing

2 echo 7e#ugger gd# started@n V $et the user kno" "hat has happened 4 s%:#ol /proc/Cpid>/exe Q !ell gd, "here to )ind the sy#,ol ta,le )or the process > #rea8 gd#_stop Q Stop at a nice stopping point ? shell touch Cflag-file> Q !ell the progra# that gd, is attached 08ore on this later2 A continue Q Continue e&ecution and stop at the correct location !he )irst gd, co##and* attach Cpid> attaches the de,ugger to the progra# 0<pid> is replaced ,y the process id o) the progra# to ,e de,ugged 2 !he de,ugger is no" in control o) the progra# %ctually i) "e "ere in a #ini#alist )ra#e o) #ind, "e "ould stop here @ut the de,ug session is in a sorry state !he sy#,ol ta,le has not ,een loaded and don5t kno" i) "e stopped in the correct thread or at a kno" location So "e e&ecute a )e" #ore co##ands to #ake things a little nicer !he ne&t co##and* echo 7e#ugger gd# started@n outputs a greeting #essage !hat "ay the user that "e5ve started the de,ugging process Ge&t "e load the sy#,ol ta,le 'or that "e need the na#e o) the progra# )ile One "ay o) )inding this is to talk look at the progra# na#e and do a P%!H search )or the e&ecuta,le )ile @ut $inu& is nice to provide a sy#,olic link )ro# /proc/CpidH/exe to the e&ecuta,le, so "e Kust e&ploit this )eature to load our sy#,ol ta,le Page 84 Copyright 2008, Steve Oualline

C++ Hackers Guide s%:#ol /proc/Cpid>/exe

Steve Oualline

Go" "e tell gd, to stop at a good place ;n )act "e5ve de)ined a good place to stop called gd#_stop, so "e5ll set a ,reakpoint there #rea8 gd#_stop 6hen the de,ugger is attached to a progra#, the progra# stops !he pro,le# is "e don5t kno" "here the progra# is stopped ;t could ,e 80 levels deep into so#e )unction called ,y de#ug_:e 6hat "orse, "e could ,e dealing "ith a threaded progra# ;n that case "e #any not even ,e stopped in the thread that caused the error !he solution to this pro,le# is to set a stop in a kno" location 0gd#_stop2 and tell the de,ugger to continue 6hen "e stop at gd#_stop "e kno" "here "e are and "e are sure to ,e in the correct thread %)ter de#ug_:e starts gd, it "aits around )or the de,ugger to start !his is done using the loop* ]E: ]D: ]A: ]]: while &access&,lag_,ile) 5_/4' R= ;' K sleep &('; L

!his loop "aits around )or a )lag )ile to ,e created %s soon as it sho"s, the progra# kno"s that the de,ugger is running and it can continue ;n order to create the )lag )ile, "e issue the )ollo"ing co##and to gd,* touch C,lag_,ileH 'inally "e tell gd, to continue %t this point the e&ecution o) the progra# continues )or a short "hile until the progra# reaches gd#_stop !he code to do all this "ork is listed in the )ull de,ugJ#e c #odule at the end o) this hack 8ostly it5s a #atter string processing to get the co##ands into the co##and )ile Go" let5s talk a,out the actual invocation o) the gd, co##and ;deally "e should ,e a,le to Kust use a syste# call to e&ecute the co##and* gd# NNco::and=<command-file> ;n this e&a#ple <command-file> "ill ,e replace ,y a te#porary )ile containing the co##ands "e listed a,ove @ut it5s not as si#ple as that ;t never is

Page 8>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

6hat is our progra# is a dae#on running in ,ackground ;t has no standard in and standard out ;) "e started gd, there "ould ,e no ter#inal in "hich to type co##ands % solution to this pro,le# is to start our o"n ter#inal "indo" !his done "ith the co##and* xter: N#g red Ne gd# Vco::and=<command-file> !his starts a ne" &ter# progra# in "hich our de,ugger "ill run 6e set the ,ackground to red using the options N#g red -ed is used ,ecause it gets our attention @esides the red screen o) death sounds ,etter than the ,lue screen o) death 'inally "e tell &ter# to e&ecute the gd, co##and through the use o) the Ne option Go" that "e5ve done all this let5s see ho" this )unction #ight ,e used in a progra# Here5s so#e code that handles a varia,le that it either ,lack or "hite 0at least under nor#al, sane circu#stances2* Jinclude de#ug_:e=h // ==== switch &#lac8_or_white' K case 1 A.4: do_#lac8&'; #rea8; case -II+!: do_white&'; #rea8; de,ault: std::cerr CC IN+!0NA std::endl; de#ug_:e&'; #rea8; L

!00/0: I:possi#le color CC

;n this case the varia,le #lac8_or_white undergoes a sanity test ;) things are insane "e start the de,ugger ote: !his only "orks )or progra#s "hich are used internally ;) you are giving a progra# to a custo#er "ithout source code, this syste# is not that use)ul

!he )ull source code )or the de,ugJ#e c )ile )ollo"s Page 8? Copyright 2008, Steve Oualline

C++ Hackers Guide (: *: ?: B: F: E: D: A: ]: (;: ((: (*: (?: (B: (F: (E: (D: (A: (]: *;: *(: **: *?: *B: *F: *E: *D: *A: *]: ?;: ?(: ?*: ??: ?B: ?F: ?E: ?D: ?A: ?]: B;: B(: B*: B?: BB: BF: Page 8A

Steve Oualline

/************************************************ * de#ug_:e NN A :odule to start the de#ugger * * ,ro: a running progra:= * * * * -arning: +his code is inux speci,ic= * ************************************************/ Jinclude Cstdio=hH Jinclude Cunistd=hH Jinclude Cs%s/para:=hH Jinclude Cstdli#=hH Jinclude 9de#ug_:e=h9 static int in_gd# = ;; // +rue i, gd# started

/************************************************ * gd#_stop NN A place to stop the de#ugger * * * * Note: +his is not static so that the * * de#ugger can easil% ,ind it= * ************************************************/ $oid gd#_stop&$oid' K print,&9"d# stop@n9';,,lush&stdout'; L /************************************************ * start_de#ugger NN Actuall% start * * the de#ugger * ************************************************/ static $oid start_de#ugger&$oid' K int pid = getpid&'; // /ur 3I7 // +he na:e o, the gd# ,ile char gd#_,ile_na:eTPAS3A+I !NU; // 5ile that's used as a ,lag // to signal that gd# is running char ,lag_,ileTPAS3A+I !NU; // +he ,ile with the gd# in,or:ation in it 5I ! *gd#_,ile; // .o::and to start xter: Copyright 2008, Steve Oualline

C++ Hackers Guide BE: BD: BA: B]: F;: F(: F*: F?: FB: FF: FE: FD: FA: F]: E;: E(: E*: E?: EB: EF: EE: ED: EA: E]: D;: D(: D*: D?: DB: DF: DE: DD: DA: D]: A;: A(: A*: A?: AB: AF: AE: AD: AA: A]: ];: Page 8B char c:dTPAS3A+I !NM(;;U; i, &in_gd#' return; /* 3re$ent dou#le de#ugs */

Steve Oualline

/* * .reate a co::and ,ile that contains * attach CpidH J Attaches to the process * echo ==== J !chos a welco:e :essage * s%:#ol /proc/CpidH/exe * J oads the s%:#ol ta#le * #rea8 gd#_stop J 6et a #rea8point in * shell touch /t:p/gd#=,lag=CpidH * J .reate a ,ile that tells us * J that the de#ugger is running * continue J .ontinue the progra: */ sprint,&gd#_,ile_na:e) 9/t:p/gd#=\d9) pid'; gd#_,ile = ,open&gd#_,ile_na:e) 9w9'; i, &gd#_,ile == N2 ' K ,print,&stderr) 9!00/0: 2na#le to open \s@n9) gd#_,ile_na:e'; a#ort&'; L sprint,&,lag_,ile) 9/t:p/gd#=,lag=\d9) pid'; ,print,&gd#_,ile) 9attach \d@n9) pid'; ,print,&gd#_,ile) 9echo 9 9@7e#ugger gd# started@@n@9@n9'; ,print,&gd#_,ile) 9s%:#ol /proc/\d/exe@n9) pid'; ,print,&gd#_,ile) 9#rea8 gd#_stop@n9'; ,print,&gd#_,ile) 9shell touch \s@n9) ,lag_,ile'; ,print,&gd#_,ile) 9continue@n9'; ,close&gd#_,ile'; /* 6tart a xter: window with the * de#ugger in it */ sprint,&c:d) 9xter: N,g red 9 9Ne gd# NNco::and=\s >9) Copyright 2008, Steve Oualline

C++ Hackers Guide ](: ]*: ]?: ]B: ]F: ]E: ]D: ]A: ]]: (;;: (;(: (;*: (;?: (;B: (;F: (;E: (;D: (;A: (;]: ((;: (((: gd#_,ile_na:e'; s%ste:&c:d'; /* Now sleep until the de#ugger starts and * creates the ,lag ,ile */ while &access&,lag_,ile) 5_/4' R= ;' K sleep &('; L in_gd# = (; gd#_stop&'; L

Steve Oualline

/************************************************ * de#ug_:e NN 6tart the de#ugger * ************************************************/ $oid de#ug_:e&$oid' K start_de#ugger&'; gd#_stop&'; L

Hack +3: Makin* assert #ail%res Start the De0%**er


The Problem* % )ailed assert nor#ally Kust prints a #essage and a,orts the progra# !his is not very use)ul "hen it co#es to )inding pro,le#s ;t "ould ,e #uch ,etter i) a )ailed assert could start the de,ugger The Hack* 8arry assertion )ailure "ith de#ug_:e !he )irst thing "e need to do is to deter#ine the na#e o) the )unction that5s called i) an assertion )ails !his varies )ro# syste# to syste# !o )ind out ho" assert "orks, "e create a s#all test progra#* Jinclude CcassertH assert&-e are ,ailing R= ;'; Ge&t "e run the progra# through the preprocessor and take a look at the output Here5s a e&a#ple using the gcc C: co##and !he interesting lines are* J * 9assert=cpp9 *

Page 88

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

&static_castC$oidH &__#uiltin_expect &RR&9-e are ,ailing9 R= ;') (' _ ; : &__assert_,ail &9@9-e are ,ailing@9 R= ;9) 9assert=cpp9) ?) __30!++G_52N.+I/N__') ;'''; 'ro# this "e can see that the )unction __assert_,ail is called "hen an assertion is triggered :arlier in the output the co#piler is even nice enough to provide us "ith a prototype* extern . K extern $oid __assert_,ail & __const char *__assertion) __const char *__,ile) unsigned int __line) __const char *__,unction' throw &' __attri#ute__ &&__noreturn__''; L Go" all "e have to do is supply our o"n version o) __assert_,ail "hich calls de#ug_:e /******************************************************** * __assert_,ail NN .alled when an assert ,ails= * * 6tarts the de#ugger= * * * * Note: gcc speci,ic= 7i,,erent co:pilers use * * di,,erent internal routines to handle #ad * * asserts= * ********************************************************/ $oid __assert_,ail& const char *const what) const char *const ,ile) const int line) const char *const ,unct ' K print,&9Assert ,ailed: \s@n9) what'; print,&95AI 20! at: \s:\d@n9) ,ile) line'; print,&95unction is \s@n9) ,unct'; de#ug_:e&'; a#ort&'; L One thing to notice a,out this )unction is that it calls a#ort a)ter de#ug_:e= !hat5s to prevent a careless progra##er )ro# typing continue in a de,ugging session and atte#pting to continue a o,viously )ailed progra# Page 87 Copyright 2008, Steve Oualline

C++ Hackers Guide The History of debug_me

Steve Oualline

!he de#ug_:e )unction "as originally "ritten to de,ug a #o,ile phone si#ulation progra# !he progra# had ,een a,andon )or a long ti#e ,ecause it "as e&tre#ely ,uggy 6hen ; got it the progra# "as e&tre#ely ,uggy and e&tre#ely out o) date !he progra# #ade e&tensive use o) threads and )re=uently a thread "ould crash 'inding out "hich thread had cause the pro,le# "as e&tre#ely di))icult as the gd, thread related co##ands didn5t "ork too "ell on this syste# So ; invented de#ug_:e to help solve this pro,le# One interesting aspect o) this progra# "as its unusual )ailure #odes Luite )re=uently a thread "ould trigger an assertion )ailure and start the de,ugger 6hile the de,ugger "as staring, another thread "ould )ail and atte#pt to start the de,ugger %ny progra##er can "rite code that causes an assertion to )ail and a,ort the progra# ;t takes a real hacker to get #ultiple assertions to )ail in a single run

Hack .5: Stoppin* the 'ro*ram at the Ri*ht 'lace


The Problem: (ou kno" that the progra# )ails during the >8B iteration o) the loop ;) you put in a ,reakpoint you5ll have to type continue >8A ti#es ,e)ore you get to the pro,le# The Hack: Create a de,ugging point So#e de,uggers #ake it di))icult to stop the progra# "hen you "ant to, like the >8Bth pass through a loop So ho" get you get around this li#tiationS @y putting in so#e te#porary code Kust )or the de,ugger 'or e&a#ple* Ji,nde, WWW $oid de#ug_stop&' K // +he de#ugger can stop here L Jendi, /* WWW */ // === Page 70 Copyright 2008, Steve Oualline

C++ Hackers Guide ,or &i = ;; i C F;;;; MMi' K Ji,nde, WWW i, &i == BAD' de#ug_stop&'; Jendi, /* WWW */ // 3ro#le: code ,ollows

Steve Oualline

Go" all "e have to do is to start our de,ugger and put a ,reakpoint in

de#ug_stop -ight ,e)ore the pro,le# occurs this procedure "ill ,e called

thro"ing us into the de,ugger 6e can then single step through the progra# until "e )ind the error !here are a couple o) things to note a,out this code 'irst de,ugJstop is a glo,al )unction !he reason )or this is that so#e de,uggers have a hard ti#e )inding static )unctions !he reason "e use Ji,de, WWW )or our de,ugging code is descri,ed in Hack B2 @asically it5s an easy to "ay to identi)y te#porary code

Page 71

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter %: Commenting and *a+igation Hacks


6hen ; studying co#puter science at the university, the ne&t great thing that "as co#ing "as the technology to typeset progra#s and ,reak out o) the #onospaced )ont that "e then used )or progra##ing !hat "as thirty years ago !oday "e still progra# using #onspaced %SC;; characters Go typesetting, no graphics Q nothing that "asn5t availa,le thirty years ago 06ith the possi,le e&ception o) synta& highlighting 2 Ho"ever hackers have never let inade=uate technology stand in our "ay ;n this chapter "e present so#e o) the hacks that let us get around the li#itations o) our progra##ing environ#ent

Hack .1: Creatin* Headin*s "ithin Comment


The Problem: !he )ile )or#at doesn5t support headings, so ho" do you set your headings apart The Hacks* !here are a nu#,er o) tricks that you can play "ith your co##ents 'irst headings can ,e underlined or dou,le underlined /* * * * * * * * * * * * * * * * * * A I:portant Ieading NNNNNNNNNNNNNNNNNNNN Iere we put a paragraph discussing the stu,, we'$e headlined a#o$e= A Ver% I:portant Ieading ========================= Ieadings li8e the one a#o$e can #e used to denote $er% i:portant sections= MNNNNNNNNNNNNNNNNNNNNNNNNNM O +his is al:ost shouting O MNNNNNNNNNNNNNNNNNNNNNNNNNM Now here's so:ething that reall% stands out=

!here are other "ays o) indicating a #aKor section ,reak 'or e&a#ple you can #ake a heading that spans the entire line* /* Page 72 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

* CCCCCCCCCCCCCCCCC I// 6ection 5ollows HHHHHHHHHHHHHHHHH */ %nd )inally "e have a really i#portant section header* /******************************************************** ********************** -A0NIN" ************************* ********************** -A0NIN" ************************* ********************** -A0NIN" ************************* ********************************************************/ /* * 7o not atte:pt to dri$e hea$% eYuip:ent while reading * this #oo8= */

Hack .2: Emphasi<in* "ords "ithin a para*raph


The Problem: !he a,ove "orks )or headings, ,ut "hat do you do "hen you "ant to typeset "ords "ithin a paragraph The Hack* Creative use o) /H3 and other characters can help e#phasiFe "ords 'or e&a#ple* /* * 6o:e people consider all capitals to #e 6I/2+IN"R * * 1ut there are other wa%s to **e:phasi<e** a word= * Pore that CConeHH in ,act= A,ter all there are a * nu:#er o, ==,un== characters %ou can pla% around with= */

Hack .3: '%ttin* Dra"in*s In Comments


The Problem* !here are no dra"ing )unctions in progra# editors ;t5s i#possi,le to put )igures and graphs inside co##ents The Hack: .se %SC;; art Pri#itive )igures can ,e dra"n using Kust the %SC;; characters e&a#ple, the )ollo"ing co##ent docu#ents the layout o) a G.;*
10

'or

10 %ctually so#e very sophisticated %SC;; art can ,e produced Yust not ,y progra##ers

Page 74

Copyright 2008, Steve Oualline

C++ Hackers Guide /* * * * * * * * */ MNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNM O Na:e: ____________________ O O Address: ____________________ O O .it%: ____________________ O MNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNM OCN NAP!_6I[! NHO O OCNNN 1 AN4_6I[! NNNNHO

Steve Oualline

;n this e&a#ple "e5ve not only created a )igure ,ut at the sa#e ti#e docu#ented the constants "e used )or the di#ension constants NAP!_6I[! and

1 AN4_6I[!

Hack .(: 'ro1idin* User Doc%mentation


The Problem: (ou need to provide user docu#entation )or your progra# Oualline5s la" o) docu#entation states* 70\ o) the ti#e the docu#entation is lost Out o) the re#aining 10\, 7\ o) the ti#e it "ill ,e so out o) data as to ,e totally useless !he re#aining \1 o) the ti#e you have the correct docu#entation and the correct revision o) the docu#entation it "ill ,e "ritten in Yapanese 11 The Hack: .se Perl5s PO9 docu#entation syste# PO9 0Plain Old 9ocu#entation2 )or#at is a si#ple, yet )airly ro,ust "ay o) e#,edding docu#entation in a progra# (ou can easily put a PO9 docu#entation section at the ,eginning o) your progra# 'or e&a#ple* /* * +he ,ollowing is the docu:entation ,or the progra:= * 2se the =pod =head( NAP! sol$e_it N 6ol$e the worlds pro#le:s =head( 6GN/36I6

11 !he )irst ; told this Koke to a colleague he laughed )or a,out three #inutes then handed #e his copy o) Hitachi 'ortran Eolu#e ;; 0Eolu#e ; "as at the translator5s 2

Page 7>

Copyright 2008, Steve Oualline

C++ Hackers Guide sol$e_it TNuU pro#le: =head( 7!6.0I3+I/N

Steve Oualline

+he ICsol$e_itH progra: sol$es all the worlds pro#le:= `ust input the pro#le: on the co::and line and the solution will #e output= =head( /3+I/N6 +he ICsol$e_itH ta8es the ,ollowing options: =o$er B =ite: 1CNuH 6ol$e the pro#le: ,or the uni$erse) not Xust the world= =#ac8 =head( IPI+A+I/N6

.urrentl% totall% uni:ple:ented= =head( A2+I/0 6te$e /ualline) !CltHouallineZwww=oualline=co:!CgtH= =head( ./3G0I"I+ .op%right *;;D 6te$e /ualline= +his progra: is distri#uted under the "3 = =cut */ Go" you can run your source code through one o) the PO9 converters such as pod2te&t and get a )or#atted version o) your docu#entation*

NIA0

sol*e2it - Col*e t e worlds #ro'lems sol*e2it =-!> #ro'lem

CKNGPC:C

Page 7?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

D0C1&:PT:GN T e Nsol*e2itN #ro"ram sol*es all t e worlds #ro'lem. <!st in#!t t e #ro'lem on t e command line and t e sol!tion will 'e o!t#!t. GPT:GNC T e Nsol*e2itN ta@es t e +ollowin" o#tions: -! Col*e t e #ro'lem +or t e !ni*erse, not M!st t e world.

L:A:TIT:GNC 1!rrently totally !nim#lemented. I-T$G& Cte*e G!alline, Oo!allinePwww.o!alline.comQ. 1GPK&:B$T 1o#yri" t 200) Cte*e G!alline. T is #ro"ram is distri'!ted !nder t e BPL.

Other converters include pod2ht#l, pod2#an, as "ell as others

Hack .+: Doc%mentin* the 7'I


The Problem: Ho" do you docu#ent the %P; to a li,rary you5ve "ritten in a nice "ay Oualline5s $a" o) 9ocu#entation applies to %P; docu#entation as "ell as the user #anual The Hack: .se do&ygen to auto#atically generate docu#entation )ro# special co##ents in the code

Page 7A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his tool allo"s you to use specially )or#atted co##ents to inCline docu#entation inside your code Here5s a short e&a#ple* /** * @#rie, +he #asic report speci,ication * * +his class co:pletel% descri#es all the para:eters * needed to produce a report */ class 0eport6pec K /** Na:e o, the report */ pu#lic: const char* const na:e; /** * Add a new report para:eter * * @para: na:e Na:e o, the para:eter * @para: $alue Value o, the para:eter */ $oid add_para:& const char* const na:e) const char* const $alue '; L; 6hen run through 9o&ygen this produces set o) H!8$ docu#entation pages "hich can ,e vie"ed in any ,ro"ser*

Page 7B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'igure 1* 9o&ygen docu#entation as H!8$

Page 78

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his syste# does provide an e&cellent syste# )or docu#enting your progra#s i) you5re "illing to )ollo" the conventions and "rite the co##ents correctly On the other hand i) you5re dealing "ith a lot o) code that didn5t do this, check out the ne&t hack

Hack ..: Use the Lin%& Cross Re,erence to =a1i*ate Lar*e Codin* 'roFects
The Problem: (ou5re dealing "ith a poorly designed ?,000,000 line proKect and you5re getting lost The Hack* .se the $inu& Cross -e)erence to generate a cross re)erenced version o) your code !he $inu& Cross -e)erence 0l&r212 is a progra# "hich produces a hyperCte&t ,ased #arkup o) your code (ou can get a copy )ro# http*11l&r linu& no1 ;t has a nu#,er o) nice )eatures such as the a,ility to locate any identi)ier in the code and sho" every place that it is used 'igure 2 sho"s the syste# ,eing used to ,ro"se a )ile

12 9on5t let the na#e )ool you ;t "ill cross re)erence things other than $inu&

Page 77

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'igure 2* $inu& Cross -e)erence 0'ile Eie"2


On line >> there is a )unction that uses the audit_entr% structure 6e "ould like to kno" "hat an audit_entr% is Clicking on the identi)y takes to a page "hich lists every place that the identi)ier is used 0See 'igure 4 2

Page 100

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'igure 4* ;denti)ier .se Page


!his sho"s use that the identi)ier is de)ined in the )ile kernel1audit h 0line B?2 and used in the )ile kernel1audit)ilter c in lots o) places Clicking on the )irst entry gives us the de)inition as sho"n in 'igure >

Page 101

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'igure >* 9e)inition o) audit_entr%=


$T- is a very po"er)ul cross re)erencing tool @ut it is also so#e"hat di))icult to setup and get running (ou5ll need a "orking "e, server )or the data generated %lso you5ll need a good "orking kno"ledge o) Perl in order to adapt the code )or your syste# 0'or your Perl hackers out there $T- contains so#e o) the #ost co#ple&, advanced regular e&pressions out there 2 @ut i) you are dealing "ith a huge a#ounts o) code this tool can ,e a li)esaver

Page 102

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter ,: Pre-processor hacks


C++ is actually t"o languages, a #acro preprocessor language and a co#piled language So "hat you can5t hack is the ,ase language you can atte#pt to hack in the preCprocessor

Hack ./: Usin* the 're4processor to Generate =ame Lists


The problem: C++ does not have a "ay o) getting the te&t )or# o) a enum 'or e&a#ple* enu: state K6+A+!_"//7) 6+A+!_1A7) 6+A+!_2N4N/-NL; // 7oesn't wor8 right std::cout CC 9"ood is 9 CC 6+A+!_"//7 CC std::endl; !he result is "ood is ; 6hat "e "ant is "ood is 6+A+!_"//7 The Hack: .se the preCprocessor to de)ine a list o) ite#s in di))erent )or#ats 'irst "e de)ine a #acro that contains the list o) ite#s "e "ish to use* Jde,ine 6+A+!_ I6+ @ 7&6+A+!_"//7') @ 7&6+A+!_1A7') @ 7&6+A+!_2N4N/-N' !he #acro 7 0"hich "e haven5t de)ined yet2 enclosed ite# 6e "ill no" use the 9 #acro to de)ine the list in a variety o) "ays* Jde,ine 7&x' x enu: state K 6+A+!_ I6+L Junde, 7 Gotice that "e i##ediately unde)ine the 7 #acro a)ter it5s use !his prevents this te#porary #acro )ro# ,eing accidentally reused later on in the code Go" let5s de)ine a list o) na#es Page 104 Copyright 2008, Steve Oualline

C++ Hackers Guide Jde,ine 7&x' Jx const char* const state_na:e = K 6+A+!_ I6+ L; Junde, 7

Steve Oualline

6e can no" output the na#e o) a state using a state#ent like* std::cout CC 9+he good state is 9 CC state_na:eT6+A+!_"//7U CC std::endl; Limitations: !his only "orks )or enu: lists "here the things are in nu#erical order ;) you assign values to ite#s this "ill not "ork 'or e&a#ple* enu: error_code K1A7=BB) V!0G_1A7=FF) +!00I1 ! = ]]]L; !he ne&t hack solves this pro,le#

Hack .2: Creatin* Word Lists 7%tomaticall!


The Problem: (ou need to create a enum list "ith speci)ic values 'or e&a#ple* S!%-! is ?, P%.S: is B and %@O-! is 2? The Hack* % clever preCprocessor hack can easily handle this $et5s start ,y de)ining our list* Jde,ine ./PPAN7_ I6+ .&./PPAN7_6+A0+) F') .&./PPAN7_3A26!) D') .&./PPAN7_A1/0+) *F' @ @ @

Go" let5s create a #acro to de)ine the enum declaration* Jde,ine .&x)%' x = % enu: ./PPAN76 K ./PPAN7_ I6+ L; Junde, . !he ne&t step is to de)ine the na#e to id nu#,er #apping* Jde,ine .&x)%' K%) JxL struct c:d_nu:#er_to_na:e K int c:d_nu:#er) char* c:d_na:e; L c:d_nu:#er_to_na:eTU = K ./PPAN7_ I6+ ) KN() N2 L Page 10> Copyright 2008, Steve Oualline

C++ Hackers Guide L; Junde, .

Steve Oualline

!he use o) nested #acros like this is e&tre#ely use)ul "hen it co#es dealing "ith data that #ust ,e e&pressed #ore than one "ay Our hacks have concentrated on enum de)initions, ,ut this hack has other uses ,eyond these si#ple progra##ing e&a#ples

Hack .3: 're1entin* Do%0le Incl%sion o, Header #iles


The Problem: %ll header )iles should include any other headers they need !his can easily result in a single )ile ,eing included #ultiple ti#es @ut de)ining the sa#e thing #ultiple ti#es can cause lots o) pro,le#s The Hack* %dd /dou,le include3 protection to your header )iles 'or e&a#ple* // 5ile de,ine=h Ji,nde, __7!5IN!_I__ Jde,ine __7!5IN!_I__ // === rest o, the header ,ile Jendi, /* __7!5IN!_I__ */

Hack /5: Enclose M%ltiple Line Macros In do?"hile


The Problem: Ho" do you create a #acro that per)or#s t"o state#ents 'or e&a#ple "e "ish to create a cleanup #acro* Jde,ine . !AN_0!+20N @ close&in_,d';close&out_,d'; return; @ut this code doesn5t "ork i) "e put it in an if state#ent* i, &done' . !AN_0!+20N; :&panding this "e get* i, &done' close&in_,d';close&out_,d'; return; $et5s add a little "hitespace )or clarity* i, &done' close&in_,d'; close&out_,d'; return;

Page 10?

Copyright 2008, Steve Oualline

C++ Hackers Guide in OP Jde,ine . !AN_0!+20N @ K close&in_,d';close&out_,d'; return; L Go" our if state#ent e&pands to* i, &done' K close&in_,d';close&out_,d'; return; L;

Steve Oualline

!his is not "hat "e intended One /solution3 is to enclose the state#ents

!his "orks Sort o) !he pro,le# is i) "e try an if 1 else state#ent* i, &done' . !AN_0!+20N; else not_done_%et&'; !his gives us a synta& error "hen "e try and co#pile it 6hyS $et5s look at the e&panded code* i, &done' K close&in_,d';close&out_,d'; return; L; else not_done_%et&'; !here5s an e&tra se#icolon on the line !his didn5t ,other us "hen there "as no else, ,ut no" that there is one, the co#piler gets con)used So ho" do "e de)ine a #ultiCstate#ent #acro that can ,e used like a state#entS The Hack: .se the do 1 .hile trick 9e)ine the #acro so the state#ents are inside a do 1 .hile loop* Jde,ine . !AN_0!+20N do K close&in_,d'; close&out_,d'; return; L while &;' @ @ @ @ @

Gotice that there is no se#icolon at a)ter the while &;' :nclosing #ultiple state#ents in a do 1 .hile loop #akes the# a single state#ent !hus they can ,e used any"here a single state#ent can ,e used

Page 10A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

ote: !his is pro,a,ly the only place you legiti#ately "ant to use a do 1 .hile ;n all other cases a .hile loop is pro,a,ly si#pler and easier to understand than a do 1 .hile

Hack /1: Use 9i, 5 to Remo1e Code


The Problem: (ou need to #ake code disappear Co##enting it is one option, ,ut that "on5t "ork i) your co#piler doesn5t allo" nested co##ents The Hack: :nclose the code in a 6if 7 1 6endif ,lock 'or e&a#ple* do_it&'; Ji, ; dou#le_chec8_it&'; Jendi, ,inish_up&'; !his hack takes the code out o) your progra# @ut the =uestion re#ains, "hy not Kust delete the code %)ter all i) you really "ant it to go a"ay, delete it 9on5t leave it in the progra# ;5ve seen this hack used a nu#,er o) ti#es an each ti#e ; could see no reason )or leaving the dead code in the progra# @ut i) you ever do have a reason )or putting such code in a progra# )ile, this hack "ill keep it out o) the progra#

Hack /2: Use 9i,nde, HHH to Identi,! )emporar! Code


The Problem: So#eti#es you Kust need to keep adding diagnostics to the code until you )ind the pro,le# O) course you don5t "ant these te#porary hacks sho"ing in production code so it "ould ,e nice i) you could re#ove the# =uickly The Hack* Put the code in a 6ifndef 888 1 6endif ,lock 'or e&a#ple* read_account&'; Ji,nde, WWW sa$e_#ac8up&de#ug=(=sa$e'; std::cout CC 6tarting sort CC std::endl; Jendi, /* WWW */ #alance&'; Ji,nde, WWW Page 10B Copyright 2008, Steve Oualline

C++ Hackers Guide sa$e_#ac8up&de#ug=*=sa$e'; Jendi, /* WWW */

Steve Oualline

!he sy#,ol 888 "as chosen ,ecause it5s easy to type and no one de)ines it 0Go one sane any"ay 2 @esides it5s shorter than

9:,0-,_I%DI.:TI%3_.$D-_I_:9_T:0I%3_$4T_:/_/$$%_:/_THI/_W$,0/
!he sy#,ol #akes the te#porary code stand out like a sore thu#, and it #akes it easy to take the code out "hen you5re done Yust search )or 888 and delete all the conditional code ,locks associated "ith it

Hack /3: Use 9i,de, on the #%nction =ot on the #%nction Call to Eliminate E&cess 9i,de,s
The Problem* (ou "ant to add so#e logging ,ut only )or the de,ug relase o) the so)t"are So throughout your code you have lots o) stu)) like this* Ji,de, 7!12" de#ug_:sg&!ntering ,unction sixth_le$el_o,_hell'; Jendi, /* 7!12" */ !his is ugly and annoying !here #ust ,e a ,etter "ay The Hack: ;) you de)ine de#ug_:sg right you can get rid o) all those &ifdef state#ents and #ake our code clean 'or e&a#ple* Ji,de, 7!12" extern $oid de#ug_:sg&const char* const :sg'; Jelse /* 7!12" */ static inline $oid de#ug_:sg&const char* const' KL Jendi, /* 7!12" */ Go" in the ,ody o) the code all "e have to Kust call the )unction* de#ug_:sg&!ntering ,unction sixth_le$el_o,_hell'; ;) 7!12" is de)ined, the real )unction is called ;) it5s not then the du##y de#ug_:sg is called Since it is an inline )unction, the opti#iFer "ill re#ove the code !he nice thing a,out this is that you don5t clutter up your code "ith useless &ifdef state#ents

Page 108

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack /(: Create Code to Help Eliminate 9i,de, Statements #rom #%nction -odies
The Problem* (ou5re "riting a progra# )or #ultiple plat)or#s %s a result you have a lot o) 6ifdef state#ents sprinkled through out the code So #any in )act that they are #ake things look ugly and the code is hard to read 'or e&a#ple* $oid send_c:d&$oid' K send_c:d_start&'; Ji,de, 5!_+!S+20! send_texture&'; Jendi, /* 5!_+!S+20! */ Ji,de, 5!_./ /0 send_#ac8ground&'; i, &,oreground R= +0AN63A0!N+' send_,oreground&'; Jendi, /* 5!_./ /0 */ Ji,de, 5!_6I[! i, &si<e R= ;' send_si<e&'; Jendi, /* 5!_6I[! */ Ji,de, 5!_0!3 AG i, &pre$_c:d == '@;'' K pre$_c:d = cur_c:d; pre$_para: = cur_para:; L Jendi, /* 5!_0!3 AG */ send_c:d_end&'; L !his code is very di))icult to read !he 6ifdef directives ,reakup the logic o) the code The Hack* .se 6ifdef to de)ine out entire procedures only 'or e&a#ple, let5s take a look at the code*

Page 107

Copyright 2008, Steve Oualline

C++ Hackers Guide Ji,de, 5!_+!S+20! send_texture&'; Jendi, /* 5!_+!S+20! */

Steve Oualline

!his can ,e #uch si#pler 'irst "e use 6ifdef to control the de)inition o) the )unction send_te2tu(e* Ji,de, 5!_+!S+20! static $oid send_texture&' K // #od% o, the ,unction L Jelse inline static $oid send_texture&' K L Jendi, /* 5!_+!S+20! */ Go" )or the ,ody o) the code "e Kust put in a call to send_te2tu(e "ithout any 6ifdef $oid send_c:d&$oid' K send_c:d_start&'; send_texture&'; 6e can do the sa#e thing "ith set_#a;5g(ound and set_fo(eg(ound !he calls to these )unctions look like* send_#ac8ground&'; i, &,oreground R= +0AN63A0!N+' send_,oreground&'; @ut doesn5t this cause e&tra code to ,e put in our procedureS 6hat a,out the state#entS i, &,oreground R= +0AN63A0!N+' %ctually i) the ,ody o) sendJ)oreground is de)ined out, the opti#iFer "ill re#ove this state#ent Go" let5s look at the code Ji,de, 5!_0!3 AG i, &pre$_c:d == '@;'' K pre$_c:d = cur_c:d; pre$_para: = cur_para:; L Jendi, /* 5!_0!3 AG */

Page 110

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!o get rid o) this 6ifdef "e )irst put the code in a procedure* Ji,de, 5!_0!3 AG static inline $oid do_repla%&' K i, &pre$_c:d == '@;'' K pre$_c:d = cur_c:d; pre$_para: = cur_para:; L L Jelse /* 5!_0!3 AG */ static inline $oid do_repla%&' K // 7o nothing L Jendi, /* 5!_0!3 AG */ Go" "e can Kust put a )unction call in our code* do_repla%&'; !he key to this hack is using &ifdef to change the de)inition o) entire )unctions Since )unctions are a si#ple, logical unit o) code, "e are de)ining things in or out at the unit level !he old "ay changed the progra# at the state#ent level and "as #uch #ore con)using !ake a look at ho" #uch si#pler the ,ody o) our )unction is "hen "e use this hack* $oid send_c:d&$oid' K send_c:d_start&'; send_texture&'; send_#ac8ground&'; i, &,oreground R= +0AN63A0!N+' send_,oreground&'; i, &si<e R= ;' send_si<e&'; do_repla%&'; send_c:d_end&'; L

Page 111

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter .: /uilding Hacks


!he siFe and co#ple&ity o) progra#s is rising e&ponentially %s a result the ,uild process is also gro"ing in co#ple&ity and the ti#e to produce ,uilds is gro"ing !he $inu& kernel has over 14,000 )iles in it containing over A ? #illion lines o) code %nd to so#e people this is considered a s#all progra# (et the ,asic ,uild tools are still the #ake co##and and a co#piler @ut so#e hacks that let you get around the li#its o) this syste# and produce code =uickly and sanely

Hack /+: Don6t Use an! IWell ;eri,ication

no"nJ Speed%ps Witho%t

The Problem: !here5s no shortage o) people "ho have a great idea a,out ho" to speed up the ,uild !hey have all sorts o) reasons "hy their pet idea "ill let you co#plete a )ive day ,uild in 4 8 seconds 'or e&a#ple, the gcc co#piler has the -pipe option Gor#ally the co#piler "ill run the )irst pass o) the co#piler and "rite the output to a te#porary )ile !hen pass 2 "ill read this )ile and "rite a second te#porary %nd so on )or ho"ever #any passes are needed 6ith the -pipe option every pass is run at the sa#e ti#e the output o) one connected to the input o) the ne&t through a pipe !he theory is that ,y doing this you eli#inate the te#porary )ile, the disk ;1O )or the te#porary )ile and do everything in #e#ory So the -pipe option #ust #ake things )aster %nd i) "e needed #ore convincing "e can take a look at the kernel 8ake)iles and )ind that the option is used there and i) the $inu& kernel uses it, then it #ust ,e good The Hack: % good hacker tests the /o,vious3 ,ecause so#eti#es the /o,vious3 isn5t o,vious $et5s take the case o) the Cpipe option Co#piling a kernel "ithout the

-pipe option takes ?B*0> 6ith the -pipe it takes ?B*17 6ait a second, it took longer "ith -pipe $et5s do a )e" #ore tests*

Page 112

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

o Pipe
?B*0> ?B*0> ?A*?8 ?A*?? ?A*?>

Pipe
?B*17 ?A*18 ?A*17 ?A*1B ?A*21

'ro# this "e can see that -pipe does not #ake things )aster ;) anything it #akes the# slo"er Go" there could ,e a nu#,er o) reasons )or these results 'irst o) all disk ;1O is ,u))ered and $inu& uses lots o) ,u))ers ;t could ,e that the te#porary )iles e&ist entirely in #e#ory and never #ake it to the disk %lso there could ,e di))erent logic in the co#piler passes )or pipe 1 nonCpipe input strea#s @ut ulti#ately as hackers all "e5re concerned "ith is results and the results do not support the theory !here are lots o) cases in progra##ing "here theory and reality do not #atch $ots o) people kno" "here the slo" parts o) their code is Hackers test ,y using a pro)iler % data,ase #anuals says that inserting records, then adding an inde& is )aster than inserting inde&ed records % hacker tests So#eti#es you )ind out that the #anual is "rong %)ter all one o) the #arks o) a true hacker is so#eone "ho kno"s progra##ing and co#puters )ront"ards and ,ack"ards !hey not only kno" "hat the #anual says "ith "ork, ,ut also kno" i) the #anual is right or not The Congreve Clock ; a# into horology14 and one o) #y )avorite types o) clocks "as designed ,y Sir 6illia# Congreve 01BB2 Q 18282 Sir 6illia# is ,est kno"s )or his contri,ution to the Star Spangled @anner ;) you re#e#,er the line /and the rockets red glare,3 he invented the rockets

14 ;t5s a per)ectly clean "ord Q look it up

Page 114

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

9uring the ti#e that he lived one o) the great engineering challenges "as #aking a accurate clock Sir 6illia# "as a proli)ic inventor and turned his genius to the pro,le# o) creating a highly accurate clock !icking is one o) the #aKor sources o) insta,ility and inaccuracy in a clock !he #ove#ent o) gears is a pro,le# and the less they #ove the ,etter One "ay to solve this pro,le# is ,y using a very long pendulu# ;n )act the longer the ,etter Congreve ca#e up "ith another solution !he result "as the Congreve Clock or the :&tre#e 9etached :scape#ent Clock as he called it % ,all is dropped on an inclined plane and allo"ed to roll do"n a track 6hen it reaches the end it trips a lever and the plane tilts the other "ay the the ,all rolls do"n to the other end !his process can take 1? to 40 seconds depending on the clock Congreve calculated that his clock design "as the e=uivalent or a conventional clock "ith a si&ty )oot pendulu# %s a result his clock should ,e accurate to "ithin a second a #onth Go" 6illia# Congreve "as a #aKor inventor, engineer, and scientist He had a great deal o) logic and calculations to ,ack up his clai# !he design "as per)ect and the engineering i#pecca,le :&tensive though and design "ent into creating the super accurate Congreve Clock :&cept it didn5t "ork !urns out that "hile a pendulu#s has a natural )re=uency a ,all rolling do"n a path does not :very speck o) dust, every te#perature change caused inaccuracy in the clock %nd ; "on5t even go into the other pro,le#s "ith his design !he goal "as )or a clock "ith an error rate o) less than a second a #onth @ut in )act a good Congreve Clock is only accurate to a,out t"enty #inutes a day

Page 11>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'igure ?* % Congreve Clock

Hack /.: Use *make 4F to speed %p compilation on d%al processor machines


The Problem: Co#piling ,ig progra#s takes a long ti#e 6e need so#e "ay to #ake things )aster 6e have a dual processor #achine ;s there any "ay to #ake the ,uild )aster other than to start t"o #akes at the sa#e ti#e The Hack: .se the -j )lag o) g#ake to #ake )ull use o) a dual processor syste# 8any #odern co#puters today have #ore than one processor Got only can you purchase high end #other,oards "hich support 2 or > CP.s, ,ut the ,oth ;ntel and %89 produce dual core #icroprocessors "hich have the e=uivalent o) t"o CP.s on a single chip

Page 11?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he GG. #ake co##and 0installed as g#ake on #ost syste#s2 has an option to help #ake opti#al use o) #ultiple processor syste#s !he -j< )lag tell the #ake progra# to try and do t"o co#piles at the sa#e ti#e ;deally this should result in cutting the co#pile ti#e in t"o !here are so#e li#itations to this syste# 'irst o) all it5s possi,le )or co#pilation errors to appear out o) order 'or e&a#ple, nor#ally i) out co#pile the )iles alpah cpp and ,eta cpp you #ight see* alpha=cpp:?: 6%ntax error alpha=cpp:D: Another s%ntax error #eta=cpp:?: 6%ntax error #eta=cpp:D: 6crewed up again 6ith -j< you #ight see* alpha=cpp:?: 6%ntax error #eta=cpp:?: 6%ntax error alpha=cpp:D: Another s%ntax error #eta=cpp:D: 6crewed up again !he other pro,le# is that ,adly )or#ed 8ake)iles #ay "hen you use -j< 0or higher2 @ut is -j< really e))ective or is it Kust another -pipeS !ests sho" that on a dual processor syste# -j< actually does "ork Here5s the results*

o 23
?A*17 ?A*18 ?A*17 ?A*1B ?A*21

23"
27*>B 27*>4 27*>8 27*>2 27*>>

23$
27*48 27*>? 27*>4 27*>2 27*>?

Go" Kust ,ecause it "orks on #y syste# doesn5t #ean it "ill "ork on yours @ut "ith a little e&peri#entation you should ,e a,le to )ind the opti#al #ake settings (4treme Parallel Processing Hackers al"ays "ant to kno" ho" the syste# ,ehaves in e&tre#e conditions !he -j< and -j= s"itches are rather #ild !hey "ill only start t"o or )our Ko,s 6hat happens i) "e increase the nu#,er

Page 11A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;) no nu#,er is supplied and you Kust -j alone, g#ake "ill start as #any Ko,s as possi,le at the sa#e ti#e ; tried this once on a #aKor piece o) so)t"are ;t "as the only ti#e ; ever sa" the load average go a,ove 1,0001> ;5# not sure ho" #uch higher the load average "ent ,ecause at that point the syste# #onitoring tools started to hang 0!hey couldn5t get any CP. cycles 2 !he syste# "as o,viously paging like craFy and really ,eating up the disk O,viously trashing1? "as going on and killing the syste#, so at this point ; re,ooted 0Couldn5t kill the processes ,ecause the shell couldn5t get enough CP. to #ake a di))erence 2

Hack //: 71oid Recompilin* 0! Usin* ccache


The Problem* -epeated co#pilation results in a lot o) needless "ork 6e all kno" the drill !o create a clean ,uild you need to e&ecute the )ollo"ing co##ands* :a8e clean :a8e :a8e install !he reason you need a #ake clean is that so#eti#es so#e "ill chang e the 8ake)ile and change so#ething like )lags or si#ilar ite#s !hese changes are not tracked ,y the #ake co##and %s a result only sure "ay to get a good ,uild is to reco#pile everything @ut #ost o) your )iles have pro,a,ly not changed since the last ,uild So you5re ,asically reproducing the sa#e )ile that you did the last ti#e you co#piled !his duplication o) e))ort takes ti#e and #akes the ,uild longer The Hack* .se the ccache progra# !he ccache progra# caches co#piled output and i) you try to co#pile the sa#e source again, gets the o,Kect )ile )ro# the cache !he result is tre#endously )aster co#plication speeds at the e&pense o) disk space @ut given the cost o) disk space today it5s "ell "orth the e))ort
1> 'or the nonC$inu& types out there, the load average is a #easure o) ho" #any Ko,s the syste# is trying to run at once % load average o) 0 1 to 4 0 is typical %nything over 10 is considered e&tre#e % load average o) 1,000+ is an indicator o) ,oth e&tre#e load and e&tre#e stupidity on the part o) the user 1? !hrashing is "here the syste# spends #ore ti#e s"itching resources around 0disk, #e#ory, etc 2 than it does getting "ork done

Page 11B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!o use the ccache progra# si#ply insert the ccache co##and ,e)ore each co#plication progra# in your 8ake)iles 'or e&a#ple* hello=o: hello=cc ccache gcc Ng Nc hello=cc 6hen this progra# is e&ecuted ccache "ill per)or# the )ollo"ing operations* 1 -un the )ile hello cc through the preCprocessor 2 Check the #d?su# o) the result against any stored checksu# )ound in the cache directory 4 ;) a #atch is )ound, the o,Kect is supplied )ro# the cache > Other"ise the co#piler is run and the results stored in the cache )or )uture use !here are a huge nu#,er o) details that have ,een glossed over, ,ut that5s the ,asic idea !he ccache progra# is a si#ple and very e))ective "ay o) speeding up repeated ,uilds !he ccache progra# is availa,le )ro# http*11ccache sa#,a org

Hack /2: Usin* ccache Witho%t Chan*in* 7ll :o%r Make,iles


The Problem: (ou5ve got a legacy application "ith e&iting 8ake)iles (ou "ish to use ccache ,ut you don5t "ant to edit every one o) the ?00 8ake)iles to get the Ko, done The Hack* .se the sy#,olic link )eature o) ccache !he hackers "ho created ccache anticipated this progra# ;) you create a sy#,olic link )ro# the ccache progra# to the co#piler 'or e&a#ple, i) you use gcc you can ena,le ccache ,y e&ecuting the )ollo"ing co##ands* ^ ln Ns /usr/local/#in/ccache /ho:e/:e/#in/gcc ^ 3A+I=/ho:e/:e/#in:^3A+I ; export 3A+I !he )irst co##and creates a link ,et"een ccache and a gcc co##and in the local directory !he second co##and #akes sure that 1ho#e1#e1,in1gcc is the )irst gcc in the path So "hen the 8ake)ile e&ecutes gcc the co##and 1ho#e1#e1,in1gcc is run !his really ccache "hich is s#art enough to kno" that it is ,eing run through a sy#,olic link Page 118 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;t then per)or#s the nor#al operations Kust as i) you and edited the 8ake)ile and added a ccache co##and to each co#pilation rule ote: (ou pro,a,ly "ant to add the P%!H co##ands to your pro)ile or ,ashrc so they are e&ecuted each ti#e you start a ne" shell

Hack /3: Distri0%te the Workload With distcc


The Problem: (ou have to co#pile a really ,ig proKect and ccache is Kust not )ast enough The Hack* ;) you have access to a lot o) ,uild #achines you can use distcc !he distcc progra# is availa,le )ro# http*11distcc sa#,a org1 !he tool is designed to "ork "ith the #ultiple Ko, option o) g#ake 'or e&a#ple "hen you e&ecute the co##and g#ake CK> the g#ake progra# "ill try and start )our co#pilation Ko,s at once 6ith distcc in place each o) these )our Ko,s "ill ,e sent to a di))erent #achine !he distcc progra# operates #uch like ccache (ou activate it ,y putting distcc in )ront o) your co#pilation co##ands 'or e&a#ple* ,oo=o: ,oo=cpp distcc gMM Nc N-all ,oo=cpp (ou5ll also need to con)igure the syste# ,y supplying distcc "ith a list o) #achine it can use )or ,uilding and installing distcc as a server on the ,uild #achines !he distcc and ccache tools are designed to "ork together So i) you5re )aced "ith having to do repeated large ,uilds, these tools can #ake your ,uild #uch )aster

Page 117

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter &: 0ptimi1ation Hacks


Hack 25: Don6t 8ptimi<e Unless :o% Reall! =eed to
The Problem: Pre#ature Opti#iFation (ou have a progra# that "orks Kust )ine !he progra# does not really use up a lot o) CP. and gets the Ko, done in a reasona,le ti#e @ut i) you opti#iFe it you5re sure you can shave a )e" seconds o)) the run ti#e 6hat do you doS The Hack: 9o nothing One o) the hardest things )or a progra##er to do is to not progra# @ut unless there is a co#pelling need )or opti#iFation, don5t do itN Si#ple "orking code al"ays e&ecutes )aster than opti#iFed nonC"orking code %lso si#ple "orking code is easier to #aintain and enhance than clever, opti#iFed code %)ter all "ho cares i) it takes ? seconds instead o) 4 to start your progra# ;n #ost cases you progra# is pro,a,ly not CP. ,ound any"ay ;) you are doing large scale data #anipulation such as video processing, creating virtual "orlds, or large scale data co#pression then opti#iFation #akes sense @ut #ost progra#s do not )all into these categories $eave "orking code alone One o) the surest "ays o) introducing a ,ug is to try and opti#iFe so#ething that doesn5t need it 9oing nothing is one o) the ,est progra##ing syste#s out there ;t takes no ti#e to "rite nothing, and nothing code is also the only code guaranteed to have Fero ,ugs in it So the ,est advice on opti#iFation is don5t do it unless you really have to

Hack 21: Use the 'ro,iler to Locate 'laces to 8ptimi<e


The Problem: 6here you think the slo" spots in your code are located and "here they really are located #ay ,e t"o di))erent things

Page 120

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

$et5s assu#e that you didn5t take the advice in the previous hack and have decided that you #ust opti#iFe Go" you #ust decide "hat part o) your progra# you5re going to try and #ake )aster ;n #ost progra#s there are one or t"o )unctions "hich consu#e a,out 70\ o) the CP. 8any ti#es a progra##er "ill have a good )eel )or "here his progra# is getting stuck @ut #ore o)ten than not it "ill turn out that his )eeling does not agree "ith realist %s a result i) he goes "ith his )eelings he "ill "ind up opti#iFing the "rong code and not speeding up his progra# The Hack: .se the Pro)iler !he pro)iler tells you "hich )unctions are taking up the #ost ti#e ;n #y e&perience a typical pro)iling session goes like this* ;5# in)or#ed that the )ile save )unction is taking too long ; have an idea that the logic that converts the para#eters to te&t )or saving #ay ,e the progra# %)ter all the code "as not designed to ,e e))icient and it certainly )ul)illed that design criteria So ; start up #y trusty pro)iler and try and locate the pro,le# in the save logic @ut so#ething )unny happens along the "ay !urns out that save is taking only 1110 o) the ti#e !he other 70\ is in the sorting )unction !urns out that in order to get things ready )or the save "e sort the para#eters Yust to #ake sure that they are sorted, every level o) the code sorts the# ,e)ore calling the ne&t lo"er level ;n all there are t"entyC)ive sorts done on the sa#e data !he )irst sort puts things in order and the other t"entyC)our Kust "aste ti#e 8y choice at this point is sort less o)ten or #ake sort #ore e))icient ; decide to add a )lag "hich tells #e i) the para#eter list is sorted or not !he sort )unction checks that )lag and does nothing i) the list is in order Pro,le# solved Gotice that the pro,le# "as not "here ; e&pected it to ,e ;t "as in so#e other code, "hich ; didn5t "rite ,y the "ay, "hich "as terri,ly ine))icient Had ; gone "ith #y instinct and opti#iFed the save code, ; "ould not have #ade the progra# any )aster !he #oral o) this store is use the pro)iler ;t tells you "here the code really is slo" rather than "here you think it5s slo"

Page 121

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 22: 71oid the #ormatted 8%tp%t #%nctions


The Problem: C5s )or#atted output )unctions are slo" C++5s )or#atted output )unctions are even slo"er Consider the )ollo"ing si#ple code )rag#ent* ,or &int i=;; i C *;; MMi' K print,&I is \d@n) i'; L C and C++ are co#piled languages and so are #uch )aster than interpreted languages @ut you5ve Kust added an interpreted language to your code !he interpreter is the print, call "hich #ust interpret the )or#at string I is \d@n and send the result to the screen So "hat #ust print, do to print the result* 1 -ead the string %nything that5s not a \ goes to the output 2 ;) a \ is encountered, interpret the \ speci)ication a Check )or any nu#,ers a)ter the \ indicating the siFe o) the string , 'ind the )or#at character 0in this case d2 4 9eter#ine ho" #any characters are needed to print the nu#,er > ;) the nu#,er o) characters needed to print the nu#,er is less than the nu#,er in the speci)ication, then output leading spaces ? Output the nu#,er !his is the si#pli)ied version ;) you "ant to see the )ull code do"nload a copy o) the GCC standard li,rary and look at the code yoursel) C++ )or#atted output is even "orse !he li,rary had a great deal o) )le&i,ility and lots o) ,ells and "histles %ll this general purpose ,aggage slo"s the li,rary do"n greatly The Hack: Custo# output routines

Page 122

Copyright 2008, Steve Oualline

C++ Hackers Guide static $oid two_digits&const int i' K i, &i H= (;' K putc&&i / (;' M ';''; L putc&&i \ (;' M ';''; L ,or &int i = ;; i C *;; MMi' K puts&I is '; two_digits&i'; putc&'@;''; L

Steve Oualline

;t should ,e noted that the second, opti#iFed, version is #uch longer and #ore co#ple& than the )irst one 6hat "e5ve done is replace slo" general purpose code "ith special purpose code designed )or this speci)ic task ;t5s )aster, ,ut it5s #ore co#ple& and #ore likely to contain ,ugs %gain only opti#iFe i) you #ust 0See Hack 80 a,ove 2

Hack 23: Use KK& Instead o, &KK -eca%se It6s #aster


The Problem: (ou need to incre#ent a varia,le in the )astest possi,le "ay The Hack: .se the pre)i& incre#ent 0++22 instead o) the post)i& 02++2 ,ecause it5s )aster Go" a lot o) you are pro,a,ly saying to yourselves /(ou5ve got to ,e kidding3 Go #atter "hich version ; use to incre#ent an integer the co#piler is going to generate e&actly code 'or e&a#ple in the )ollo"ing code, the generated code is e&actly the sa#e )or the t"o incre#ents* int i = (; MMi; iMM; 'or integers that is true @ut it5s not true )or user de)ined classes $et5s take a look at the steps needed to ,e per)or#ed )or each operation !he pre)i& 0++22 incre#ent #ust per)or# the )ollo"ing steps*

Page 124

Copyright 2008, Steve Oualline

C++ Hackers Guide 1 ;ncre#ent the varia,le 2 -eturn the incre#ented result !he post)i& version 02++2 per)or#s the )ollo"ing* 1 Save a copy o) the original value 2 ;ncre#ent the varia,le 4 -eturn the unincre#ented copy you saved in step 1

Steve Oualline

So )or the post)i& 02++2 version you have to #ake a copy o) the varia,le !his can ,e a costly operation $et5s take a look at ho" a typical class #ight i#ple#ent these t"o operations* class ,ixed_point K // 2sual stu,, // 3re,ix &MMx' operator ,ixed_point operator MM&' K $alue M= 5IS!7_N2P1!0_/N!; return &*this'; L // 3ost,ix &xMM' operator ,ixed_point operator MM&int' K // !xtra wor8 needed ,ixed_point result&this'; $alue M= 5IS!7_N2P1!0_/N!; return &result'; L 'or this reason al"ays use the pre)i& version o) the incre#ent and decre#ent operators to #ake your progra# #ore e))icient

Hack 2(: 8ptimi<e I?8 0! Usin* the C I?8 7'I Instead o, the CKK 8ne
;t should ,e noted that this opti#iFation is co#piler dependent Ho"ever, every co#piler ;5ve used e&hi,its this ,ehavior The Problem: !he C++ ;1O strea# is #ore )le&i,le and less error prone than it5s C counterpart @ut )or #ost syste#s, it5s also slo"er Page 12> Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Consider a progra# designed to read a )ile line ,y line and "rite it to standard out !he C++ version is* Jinclude Ciostrea:H int :ain&' K char lineTF;;;U; while &(' K i, &R std::cin=getline&line) si<eo,&line''' #rea8; std::cout CC line CC std::endl; L return&;'; L !he C version is* Jinclude Cstdio=hH int :ain&' K char lineTF;;;U; while &(' K i, &,gets&line) si<eo,&line') stdin' == N2 #rea8; ,puts&line) stdout'; L return &;'; L ;t takes 78 seconds )or the C++ progra# to copy a ,unch o) )iles to /dev/null "hile it takes the C progra# only 11 seconds to do the sa#e thing 1A The Hack: .se C ;1O in a C++ progra# "hen ;1O speed is an issue !his hack does speed up ;1O ,ound progra#s, ,ut it should ,e used "ith caution 'irst you do loose the advantages o) the C++ ;1O syste# !his includes the increased sa)ety that co#es )ro# this syste# '

1A On a $inu& syste# using GCC Eersion 4 >,4, @ut you5re a hacker Q run your o"n tests

Page 12?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

%lso the ti#ing tests presented here co#e )ro# one co#piler on one co#puter syste# (ou should per)or# si#ilar tests using your progra##ing environ#ent 6ho kno"s your co#piler #ay ,e ,etter

Hack 2+: Use a Local Cache to 71oid Recomp%tin* the Same Res%lt
The Problem: (ou have a )unction that is called repeatedly to co#pute the sa#e values !his )unction is taking a long ti#e to do its Ko, Ho" can you #ake things )asterS $et5s take a look at an e&a#ple @elo" is a (e;tangle class !he )unction ;ompute_se(ial returns a uni=ue serial string "hich is used )or sorting the shapes classes class rectangle K pri$ate: int color; int width; int height; rectangle&int i_color) int i_width) int i_height': color&i_color') width&i_width') height&i_height' KL $oid set_color&int the_color' K color = the_color; L char serial_stringT(;;U; // 2niYue I7 string char* get_serial&' K snprint,&serial_string) si<eo,&serial_string') rectN\d x \d / \d) width) height) color'; return &serial_string'; L :&a#ination o) this class sho"s that it uses the snp(intf to co#pute the serial string !his is an e&tre#ely costly )unction to use 6e need opti#iFe out this )unction i) at all possi,le The Hack: .se a local cache % s#all local cache can ,e very use)ul "hen it co#es to avoid the pro,le# o) co#puting the sa#e thing over and over again

Page 12A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'or our (e;tangle class this is acco#plished "ith so#e si#ple changes to get_se(ial )unction* char* get_serial&' K i, &dirt%' K snprint,&serial_string) si<eo,&serial_string') rectN\d x \d / \d) width) height) color'; dirt% = ,alse; L return &serial_string'; L Go" all "e have to do is #ake sure that di(t> is set any ti#e the data used to co#pute the serialJstring is changed !his includes the constructor* rectangle&int i_color) int i_width) int i_height': color&i_color') width&i_width') height&i_height') dirt%&true' KL %ny )unction "hich changes any o) the key #e#,ers #ust ,e changed as "ell* $oid set_color&int the_color' K color = the_color; dirt% = true; L !his hack trades co#ple&ity )or speed @y #aking the class #ore co#ple&, "e can #ake it )aster So this hack should ,e used "ith care (ou should only use it a)ter you5ve run your progra# through a pro)iler and #ade sure that this class is one o) the ,ottlenecks 'ar too o)ten people "ho think they are hackers opti#iFe a progra# "here they think there5s a speed pro,le# only to )ind out that they are not real hackers and don5t have a speed pro,le# "here they think they do Pro)ilers identi)y real speed pro,le#s, that5s "hy they are used )re=uently ,y real hackers !here is a price to ,e paid )or using this hack % real hackers kno"s "hen the price is "orth it

Page 12B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 2.: Use a C%stom ne"?delete to Speed D!namic Stora*e 7llocation


The Problem* (ou have a s#all class that is )re=uently allocated and deallocated )ro# the heap !he dyna#ic #e#ory allocation calls are really slo"ing do"n your progra# Ho" can you speed things upS The Hack: 8ake a custo# ne. 1 delete )or your class ; should point that this hack is tricky and not easy to i#ple#ent (ou should only use it i) you5re sure you kno" "hat you5re doing and you5re sure that ne. and delete are a pro,le# )or this class ;#ple#enting this "rong can corrupt #e#ory or cause lots o) other pro,le#s, so #ake sure you5ve read hacks Hack 80 and Hack 81 ,e)ore you start !o create your o"n ne. )or a class all you have to do is to declare it as a local operator )unction Here5s an e&a#ple* // A $er% s:all class &good ,or local new / delete' class s%:#ol K pri$ate: char s%:#ol_na:eTAU; // == usual :e:#er ,unctions $oid* operator new &unsigned int si<e' K i, &si<e == si<eo,&s%:#ol'' K $oid* ptr = local_allocate&si<e'; i, &ptr R= N2 ' K return &ptr'; L L return &::new charTsi<eU'; L $et5s go through this step ,y step 'irst "e have the )unction declaration* $oid* operator new &unsigned int si<e' K !his de)ines a operator ne. that overrides the one ,uiltCin to C++ ;t takes one para#eter, the siFe o) the ite# to ,e allocated One #istake people #ake is that they assu#e that the "hen you create a o,Kect "ho5s type is ;lass s>m#ol that the siFe o) the o,Kect is going to ,e si)eof*;lass s>m#ol+ ;t5s not ;) i) s>m#ol is the ,ase class in a derived class de)inition 0say ;lass e2tended_s>m#ol2 then "hen a e2tended_s>m#ol is allocated, the ope(ato( ne? o) s>m#ol is called "ith the siFe o) e2tended_s>m#ol Page 128 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;) you do not understand e&actly "hat ; Kust said, the don5t do this opti#iFation until you do ; suggest you per)or# so#e e&peri#ents "ith custo# ne. 1 delete operator using ,oth ,ase and derived classes 9o not try this hack in production code unless you )ully understand "hat is going onN 6e are going to assu#e that progra# allocates #ostly varia,les o) type sy#,ol and that5s "hat "e "ant to opti#iFe @ut Kust in case so#eone decided to e&tend our class, "e check the siFe i, &si<e == si<eo,&s%:#ol'' K ;) the siFe is not right, "e5ll )all through to the ,otto# o) the progra# and use the syste# ne" to allocate the #e#ory return &::new charTsi<eU'; ;) the correct siFe is given to use, that #eans "e are allocating a ne" s>m#ol so "e can use the opti#iFed #e#ory allocation* i, &si<e == si<eo,&s%:#ol'' K $oid* ptr = local_allocate&si<e'; 6e5ll leave the i#ple#entation o) lo;al_allo;ate to you ;t should ,e si#ple and )ast 0;) it5s ,ig a slo", "hat5s the point o) using itS2 'or e&a#ple, the allocator could use a )i&ed #e#ory array to hold the data Since you have a )i&ed siFe ite# and kno" so#ething a,out the e&pected allocate 1 )ree usage you should ,e a,le to #ake a very e))icient #e#ory #anager 6henever "e do a custo# ne. "e need to do a custo# delete as "ell* static $oid delete&$oid* const ptr' K i, &local_delete&ptr'' return; ::delete ptr L One )inal note, read the ne&t antiChack ,e)ore proceeding

7nti4Hack 2/: Creatin* a C%stomi<ed ne" ? delete Unnecessaril!


The Problem: !he progra##er thinks his progra# is slo" and )eels that a local ne. 1 delete "ill speed things up The ,nti2Hack* Opti#iFe your progra# ,y putting in your o"n ne. 5 delete

Page 127

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

8ost o) the ti#e i) you add in an opti#iFation "ithout running the progra# through a pro)iler and care)ully analyFing it, you "ill opti#iFe in the "rong place !he ne. 1 delete hack is tricky and dangerous (ou don5t "ant to add it unless you kno" that it "ill speed up your progra# !hat #eans you have to do your ho#e"ork 'ar too o)ten a person "ho thinks he5s a hacker, ,ut isn5t "ill per)or# the local ne. 5 delete % predicta,le series o) results generally )ollo"s 'irst the code ,reaks !hat5s ,ecause getting local ne. 5 delete operators to )unction right is tricky 0See the previous hack )or details 2 @ecause the progra##er has i#ple#ented ne. 1 delete "rong his progra# )ails in #ysterious "ays !racking these do"n takes ti#e :ventually he "ill give up or )inally get a "orking local ne. 5 delete O) course the proKect "ill )all ,ehind schedule during this process %)ter he )inally gets the ne" #e#ory #anage#ent syste# de,ugged, he "ill discover that ,ecause he didn5t do his ho#e"ork and run a pro)iler, he Kust sped up class that not part o) the ti#e critical progra# )lo" !hus the result is that the progra# is not any )aster than "hen he started So the only thing he has to sho" )or his e))ort is a skipped schedule @ut "hat did he gainS He learned a i#portant lesson in pre#ature opti#iFation % lesson you don5t have to learn the hard "ay ,ecause you read this antiChack

7nti4Hack 22: Usin* shi,t to m%ltiple or di1ide 0! po"ers o, 2


The Problem: So#e people use le)t shi)t to #ultiple ,y 2, >, and other po"ers o) 2 !hey use right shi)t to divide ,y the sa#e nu#,ers 'or e&a#ple the )ollo"ing t"o lines do the sa#e thing* i = X CC ?; i = X * A; The ,nti2Hack: .se shi)t to speed up calculations -eal hackers #ultiply ,y 8 "hen they "ant to #ultiply ,y 8 @ack in the days "hen co#pilers "ere stupid and #achines slo", i) you #ultiplied ,y 8 the co#piler generated #ultiply instructions !his could ,e =uite slo" as so#e #achines didn5t have a #ultiply instruction, so in order to per)or# this operation, a su,routine call "as used

Page 140

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

People =uickly discovered that you could use shi)t instead o) #ultiply 0or divide2 "hen using a po"er o) 2 02,>,8,1A 2 !he resulting code "as #uch )aster @ut #achines have i#proved and so has co#piler technology ;) you need to do a #ultiply, do a #ultiply !he co#piler "ill generate the )astest code possi,le to acco#plish this operation %ll you do "hen using a shi)t instead o) a #ultiply or divide is #aking your code #ore o,scure 6e5ve got "ay too #uch o,scure code no", ,e clear and si#ple .se #ultiple to #ultiply and divide to divide

Hack 23: Use static inline Instead o, inline )o Sa1e Space


The Problem: (ou need to save a )e" ,ytes 6e5ll ignore the =uestion as to "ay these )e" ,ytes "ould #ake a di))erence given the current #e#ory #e#ory siFes and prices $et5s Kust say you need to #ake #e#ory usage as s#all as possi,le The Hack* %l"ays declare inline )unctions static !he inline directive tells the co#piler to generate the code )or the )unction inCline !hat "orks )ine )or )unctions calls inside the )ile "here the )unction is declared @ut "hat happens in the )ollo"ing case* File sub.cpp inline int twice&int i' K return &i**'; L File body.cpp extern int twice&int i'; int X = twice&F';

t?i;e @ut ,ody cpp does not kno" that the t"ice is an inline )unction ;t5s
going to call it Kust like a nor#al e4tern )unction

;n this case it5s per)ectly legal )or the )ile ,ody cpp to contain a call to

Page 141

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

So the co#piler is )orced to not only generate all the inCline instances o)

t?i;e, ,ut also generate standard )unction code Kust in case so#eone )ro#
outside tries to call it 9eclaring the )unction static tells the co#piler that no one )ro# the outside is going to call this )unction and let5s it sa)ely eli#inate the standard )unction code !hus saving a )e" ,ytes

Hack 35: Use do%0le Instead o, #loat #aster 8perations When :o% Don6t Ha1e 7 #loatin* 'oint 'rocessor
The Problem: (ou are "riting code )or an e#,edded syste# and you have to use real nu#,ers ;s there a si#ple "ay o) speeding things upS The Hack* .se double instead o) float ;t5s )aster %t )irst glance this advice see#s silly :veryone kno"s that double contains #ore ,its than float there)ore it is /o,vious3 that using double is going to take longer than float .n)ortunately the "ords /o,vious3 and /progra#ing3 )re=uently inco#pati,le !he C and C++ standard states that all real arith#etic is to ,e done in double $et5s take a look at "hat goes on under the hood o) the )ollo"ing code* ,loat a)#)c; a = (=;; # = *=;; c = a M #; !he steps needed ,y the addition are* 1 Covert a to double 2 Covert # to double 4 %dd the double version o) a to the double version o) # > Convert the result to float ? Store the result in ; Conversion )ro# float to double and double to float are not cheap and all the conversions take ti#e Go" let5s look at "hat goes on "hen "e change the varia,les to double

Page 142

Copyright 2008, Steve Oualline

C++ Hackers Guide 1 %dd a to # 2 Store result in ;

Steve Oualline

!hree float 1 double conversions have ,een re#oved Since a )loating point conversion operation is e&pensive, the result is that the code using double is #uch )aster than float version @e "arned, this hack "ill not "ork on all #achines ;n particular it "ill not "ork on PCs and other #achine "hich have a )loating point processor 0!hat5s "hy "e said "e "ere doing an e#,edded progra# "hen "e descri,ed the pro,le# 2 Hard"are )loating point units al#ost al"ays convert any nu#,ers to an internal )or#at ,e)ore doing the arith#etic no #atter )or#at is used 0So#e co#pilers use the long double type to represent this )or#at 2 S#aller, e#,edded processors don5t have the lu&ury o) )loating point units so they use a so)t"are li,rary )or their )loating point ;) this is the case )or the syste# you5re "orking on, this hack "ill pro,a,ly "ork (ou should al"ays test this hack ,e)ore trying it 'loating point operations have a li)e o) their o"n and can do strange things to unsuspecting code

Hack 31: )ell the Compiler to -reak the Standard and #orce it )o )reat ,loat as ,loat When Doin* 7rithmetic
The Problem* (ou have to use )loating point on an e#,edded syste# and can a))ord the e&tra storage needed to store all the values a double Ho" can you speed things upS The Hack: !ell the co#piler to ,reak the standard -ead your co#piler docu#entation 8ost co#pilers have an option that lets you generate single precision arith#etic even though the standard calls )or dou,le precision 'or the gnu gcc co#piler this option is -fallo?-single-p(e;ision 6hen this option is ena,led then adding t"o single precision nu#,ers is done ,y adding the t"o nu#,ers Got converting, adding, and converting ,ack !urning this on #akes your progra# e&ecute #uch )aster "ith very little loss o) precision

Page 144

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

%gain, as "e5ve discussed in the last hack, this only "orks "hen you are not using a #achine "ith a )loating point processor 6hen hard"are is used, the hard"are does it5s o"n thing concerning conversions, so the co#piler option has no e))ect

Hack 32: #i&ed point arithmetic


The Problem* (ou are coding a graphics )ilter that process each o) an i#age through a )ilter :ach pi&el is de)ined a triplet o) real nu#,ers 0-,G,@2 each o) "hich is ,et"een 0 and 2?? !he )iltering algorith#s need to "ork on real nu#,ers in order to do their Ko, @ut e&a#ining the progra# you discover that they only need t"o digits o) accuracy %ny additional digits is Kust overkill The Hack: 'i&ed point arith#etic 'i&ed point arith#etic lets you do calculations "ith real nu#,ers Kust like )loating point !he di))erence is that you can5t #ove the deci#al point ;t5s )i&ed at t"o digits !he advantage is that you can i#ple#ent )i&ed point arith#etic using integers ;nteger arith#etic is #uch #uch )aster than )loating point ;n this e&a#ple "e only need the values 0 00 to 2?? 00 so "e can store the data in a short int pri$ate: // +he $alue o, the nu:#er short int $alue; !o assign our )i&ed point nu#,er a )loating point value, all "e have to do is #ultiply ,y a conversion )actor !his converts the real value to an integer suita,le )or the integer "e are using to represent the nu#,er ,ixed=$alue = real_nu:#er * (;;; /* (;; #ecause * deci:al places */ !o add and su,tract a )i&ed point nu#,er all "e have to do is add or su,tract the internal value 8ultiply is a little #ore tricky 6e need to apply a conversion )actor to #ove the i#plied deci#al point ,ack to the right place* ,_result = ,( * ,* / (;;; 'or division the conversion )actor is #ultiplied ,_result = &,( / ,*' * (;;

Page 14>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he #ath is actually )airly si#ple .n)ortunately ,ecause o) C++ rich operator set, you have to de)ine a lot o) operators !he code at the end o) this hack contains a li#ited i#ple#entation o) a si#ple )i&ed point class One )inal note, in this e&a#ple, "e use a )i&ed deci#al point t"o places to the le)t !he syste# "ould ,e a lot )aster i) "e used a )i&ed ,inary point B places to the le)t ;n other "ords, a conversion )actor o) 128 is #uch )aster than 100 ;t gives us the sa#e precision at slightly ,etter speed Jinclude Costrea:H class ,ixed_point K pri$ate: // 5actor that deter:ines where // the ,ixed point is static const unsigned int 5IS!7_5A.+/0 = (;;; // 7e,ine the data t%pe we are using ,or // the i:ple:entation t%pede, short int ,ixed_i:ple:entation; pri$ate: // +he $alue o, the nu:#er ,ixed_i:ple:entation $alue; pu#lic: // 7e,ault $alue is ; when // constructed with no de,ault ,ixed_point&' : $alue&;' KL // .op% constructor ,ixed_point&const ,ixed_point> other' : $alue&other=$alue' KL // et the user suppl% us a dou#le as well ,ixed_point&dou#le d_$alue' : $alue& static_castC,ixed_i:ple:entationH& d_$alue / static_castCdou#leH&5IS!7_5A.+/0'' ' KL // et the user initiali<ed with an integer ,ixed_point&int i_$alue' : $alue&i_$alue * 5IS!7_5A.+/0 ' Page 14? Copyright 2008, Steve Oualline

C++ Hackers Guide KL ,ixed_point&long int i_$alue' : $alue&i_$alue * 5IS!7_5A.+/0 ' KL // All the usual assign:ent operators ,ixed_point> operator = &const ,ixed_point> other' K $alue= other=$alue; return *this; L ,ixed_point> operator = &,loat other' K $alue = ,ixed_point&other'=$alue; return *this; L ,ixed_point> operator = &dou#le other' K $alue= ,ixed_point&other'=$alue; return *this; L ,ixed_point> operator = &int other' K $alue= ,ixed_point&other'=$alue; return *this; L ,ixed_point> operator = &long other' K $alue = ,ixed_point&other'=$alue; return *this; L

Steve Oualline

// .on$ersion operators operator dou#le&' const K return static_castCdou#leH&$alue' / static_castCdou#leH&5IS!7_5A.+/0'; L operator short int&' const K return $alue / 5IS!7_5A.+/0; L operator int&' const K return $alue / 5IS!7_5A.+/0; L operator long&' const K Page 14A Copyright 2008, Steve Oualline

C++ Hackers Guide return $alue / 5IS!7_5A.+/0; L // 2nar% operators ,ixed_point operator M&' const K return *this; L ,ixed_point operator N&' const K ,ixed_point result&*this'; result=$alue = Nresult=$alue; return result; L

Steve Oualline

// 1inar% operators ,ixed_point operator M & const ,ixed_point> other' const K ,ixed_point result&*this'; result=$alue M= $alue; return &*this'; L ,ixed_point operator N & const ,ixed_point> other' const K ,ixed_point result&*this'; result=$alue N= $alue; return &*this'; L ,ixed_point operator * & const ,ixed_point> other' const K ,ixed_point result&*this'; result=$alue *= $alue; result=$alue /= 5IS!7_5A.+/0; return &*this'; L ,ixed_point operator / & const ,ixed_point> other' const K ,ixed_point result&*this'; result=$alue *= 5IS!7_5A.+/0; result=$alue /= $alue; return &*this'; L // .o:parison operators #ool operator == & const ,ixed_point> other' const K Page 14B Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

return $alue == other=$alue; L #ool operator R= & const ,ixed_point> other' const K return $alue R= other=$alue; L #ool operator C= & const ,ixed_point> other' const K return $alue C= other=$alue; L #ool operator H= & const ,ixed_point> other' const K return $alue H= other=$alue; L #ool operator C & const ,ixed_point> other' const K return $alue C other=$alue; L #ool operator H & const ,ixed_point> other' const K return $alue H other=$alue; L ,riend std::ostrea:> operator CC & std::ostrea:> out) const ,ixed_point> nu:#er'; L; // Wuic8 and dirt% output operator= std::ostrea:> operator CC & std::ostrea:> out) const ,ixed_point> nu:#er' K out CC static_castCconst dou#leH&nu:#er'; return &out'; L

Hack 33: ;eri,! 8ptimi<ed Code 7*ainst the Unoptimi<ed ;ersion


The Problem: 6e5ve decided that Hack 72 "orks )or us @ut ho" can "e tell i) "e5ve i#ple#ented the class correctlyS The Hack* 6hen replacing one syste# "ith another, test t"ice and co#pare results Page 148 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

;n this Hack 72 "e started "ith pi&els represented ,y float and replaced it "ith a fi2ed_point i#ple#entation @oth versions should produce the sa#e result @ut as hackers "e kno" that there5s a vast di))erence ,et"een /should3 and /is3 !hat5s "here testing co#es in % good test to see i) the opti#iFation "as correct is to run the unopti#iFed progra# and save the results !hen run the opti#iFed version and check to see that "e get the sa#e results ;n real li)e Hack 72 "as used to speed up a sophisticated dithering algorith# )or a color inkKet printer 6hen a ,inary co#parison "as done on the output the result "ere di))erent So in spite o) "hat our high po"ered nu#erical analysis e&pert said, t"o digits "ere not enough to generate identical results Ho"ever "hen the test i#ages "ere printed, the opti#iFed results looked Kust as good to the Print Co##ittee as the unopti#iFed versions So the co#puter could tell the di))erence ,et"een the t"o algorith#s ,ut the Print Co##ittee could not ;n the inkKet ,usiness, the Print Co##ittee rules so "e kept the ne"er, )aster algorith# !here5s a #oral to this story and as soon an ; )igure out "hat it is ;5ll put it in this ,ook

Case St%d!: 8ptimi<in* 0itsDtoD0!tes


$et5s take a look ho" a hacker "ould opti#iFe a si#ple )unction !he Ko, o) this )unction is to )igure out ho" #any ,ytes it takes to store a given nu#,er o) ,its Here5s the )unction as it )irst appeared* short int #its_to_#%tes&short int #its' K short int #%tes = #its / A; i, &&#%tes \ A' R= ;' K #itsMM; L return &#%tes'; L !he )irst thing "e notice a,out this )unction is that the code is pretty ,ad %s hackers "e are )re=uently )aced "ith horri,le code

Page 147

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

; once opti#iFed a progra# that "as taking 20 hours per run do"n to the point "here it "as taking a,out 8 seconds per run Go" ;5# a good hacker, ,ut ;5# not that good !he original progra# "as very ,adly "ritten ;n de)ense o) the original progra##er, it "as the )irst progra# he had ever "ritten and he did a re#arka,ly Ko, o) i#ple#enting a sophisticated cryptographic algorith# despite not kno"ing #any ,asic )eatures o) the C language !he #its_to_#>tes )unction "as targeted )or a cell phone 0%-8 processor2 -unning the code through the co#piler and taking a look at the asse#,ly code "e )ind so#e interesting things going on 'or e&a#ple the i#ple#entation o) the line* short int #%tes = #its / A; !he generated code looks like* :o$w r() #its asr r() ? lsl r() (E asr r() (E ; ; ; ; r( r( r( r( &#%tes' = r* HH = r( CC = r( HH = #its ? &a8a r( = r(/A' (E &_' (E &_'

6hat5s going on "ith the t"o )unny instructions that shi)t the result le)t ,y 1A then right ,y 1AS %t )irst glance this is a rather useless piece o) code !he processor uses 42 ,it arith#etic On this #achine a short int is 1A ,its 6hen the syste# does the divide ,y 8 a 42 ,it result is generated So the co#piler generates t"o instruction designed to convert a 42 ,it value into a 1A ,it one !his occurs a)ter the divide and a)ter the incre#ent !his gives us a total o) > useless instructions Changing the )unction to use int instead o) short int eli#inates these instructions and #akes our code )aster !he ne&t step is to see i) "e can "rite a ,etter algorith# and eli#inate that conditional* int #its_to_#%tes&int #its' K return &#its M D' / A; L !his co#pletely eli#inates all the conditional logic an saves us a )e" #ore instructions Go" the actual ,ody o) the )unction is Kust a hand )ull o) instructions Can "e cut it do"n even #oreS

Page 1>0

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Ho" a,out cutting it do"n to 0 instructionsS ;t5s possi,le %ll "e have to is to add the inline key"ord* inline int #its_to_#%tes&int #its' K return &#its M D' / A; L Go" "hen the opti#iFer sees a line like* store_si<e = #its_to_#%tes&B('; it "ill opti#iFe it do"n to] store_si<e = E; !he )unction is not even called %ll the co#putations are ,eing done at co#pile ti#e @ut "e5re not done opti#iFing !here5s a di))erence ,et"een a )unction declared inline and one declared static inline 6hen a )unction is declared inline the co#piler "ill inline all the )unction calls it sees, then generate a regular nonCinline )unction ,ody in case so#eone )ro# the outside "ants to call this )unction !o counter this "e declare our )unction static inline and stick it in a header )ile !hus saving us a couple o) doFen ,ytes in this e&a#ple Q total Q in a 4 ?8@ progra# Go" as hackers there5s one #ore thing "e need to consider 6hat happens "hen things go "rong %)ter all "e never trust the caller to do things right and the "e can ,e called "ith a negative nu#,er 6e need to ans"er the =uestion /Ho" #uch storage does -8@ ,its take upS3 !he easiest thing to do is to assu#e that this "ill never happen and Kust ignore it @ut i) "e do this "e need to docu#ent the )act in the progra# /* * #its_to_#%tes V "i$en a nu:#er o, #its) return the * nu:#er o, #%tes needed to store the:= * * -A0NIN": +his ,unction does no error chec8ing so * i, %ou gi$e it a $er% wrong $alue %ou get a $er% wrong * result= */ %ssu#ing so#ething ,ad "ill never happen is not really a good idea %s hackers "e kno" that lots o) things that can /never happen3 actually do Checking )or the /i#possi,le3 usually a good idea Page 1>1 Copyright 2008, Steve Oualline

C++ Hackers Guide 'or e&a#ple, "e could insert an asse(t state#ent* static inline int #its_to_#%tes&int #its' K assert&#its H= ;'; return &#its M D' / A; L

Steve Oualline

!he pro,le# "ith asse(t state#ents is that they cause the progra# to a,ort ;n real li)e this code lived in a #o,ile phone and a )ailed asse(t "ould cause the phone to reset !his "as not good ,ecause "hen this happened the phone reset it "ould play the /"elco#e sound3 :nd users "ere "ondering "hy their phone "ould restart )or /no reason at all3 !he phone #aker5s /solution3 to this pro,le# "as si#ple !hey changed the code so that a a )ailed asse(t restarted the phone silently !he code "as still very ,uggy, ,ut the ,ugs ,eca#e less visi,le 0audi,leS2 to the end users %lso you should re#e#,er that assertions can ,e co#piled out, so this code provides no protection at all Since this is C++ thro"ing an e&ception is one "ay o) handling the error* static inline int #its_to_#%tes&int #its' K i, &#its C ;' throw&:e:or%_error&#its_to_#%tes'; return &#its M D' / A; L !hese error checking options are e&pensive One ine&pensive thing "e can do is to #ake sure that error can never happen Ho" do "e do thatS %ll "e have to is #ake the argu#ent 0and the return value2 unsigned6 static inline unsigned int #its_to_#%tes&unsigned int #its' K return &#its M D' / A; L 'inally there5s one #ore "ay o) dealing "ith this error Yust change the )unction to silently ignore it and return a de)ault value* static inline int #its_to_#%tes&int #its' K i, &#its C ;' return &;'; return &#its M D' / A; L

Page 1>2

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his is usually not a good idea since such code tends to hide errors in other pieces o) code ;n general you don5t "ant to silently )i& things 8ay,e output a log #essage* static inline int #its_to_#%tes&int #its' K i, &#its C ;' K log_error& Illegal para:eter in #its_to_#%tes&\d') #its'; log_error&6tandard ,ixup ta8en'; return &;'; L return &#its M D' / A; L ;n e&a#ining ,itsJtoJ,ytes "e can see that it is actually a very short )unction @ut it does illustrate so#e o) the things good hackers consider "hen "orking "ith code !hese include*

9ealing "ith lousy code

<no"ing ho" the co#piler generates code and designing your code to #ake opti#al use o) this in)or#ation

8aking #a&i#u# use o) the language )eatures such as inline and static inline

@eing paranoid1B 9eciding "hat to do "ith ,ad data

!here5s a lot to ,e learned )ro# this little progra# %s hackers "e5re al"ays learning 6e study, research, e&peri#ent, and play all to gain a ,etter understanding o) the progra##ing process

1B Yust ,ecause you5re paranoid doesn5t #ean they aren5t out to get you

Page 1>4

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 2: g++ Hacks


!he GG. gcc package is one o) the #ost C and C++ co#pilers out there !"o things lead to its popularity 'irst it5s a high =uality co#piler !he second is that it5s )ree !he GG. co#piler has e&tended the C and C++ languages in so#e use)ul "ays 0and so#e useless ones too2 ;) you are "illing to sacri)ice porta,ility the nonCstandard language can ,e very use)ul

Hack 3(: Desi*nated Str%ct%re Initiali<ers


The Problem: (ou have a structure "ith 2,000 ele#ents in it18 !o initialiFe the structure you need to speci)y 2,000 ite#s in e&act order ;t5s easy to #ake a #istake 'or e&a#ple* struct $er%_large K int si<e; int color; int ,ont; // ()]]D :ore ite:s L; // Now create a instance o, ite: $er%_large so:ething_#ig = K 6I[!_1I") 5/N+_+IP!6) ./ /0_1 A.4) // ()]]D :ore ite:s; L; ;) you spotted the #istake in the previous e&a#ple, congratulations ;) not, then you kno" "hy this hack is so needed The Hack: .se the gcc designated structure initialiFer synta&

18 'or the hu#or i#paired, ;5# e&aggerating % real hacker "ould split up so#ething this ,ig into #ultiple s#aller and #ore #anagea,le structures

Page 1>>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he gcc co#piler has a nonCstandard e&tension that lets you na#e the )ields in an initialiFation state#ents 'or e&a#ple* $er%_large so:ething_#ig = K =si<e = 6I[!_1I") =,ont = 5/N+_+IP!6) =color = ./ /0_1 A.4) // ()]]D :ore ite:s; L; @y na#ing things "e decrease the risk o) getting so#ething in the "rong order !he pro,le# is that "e have created a nonCstandard progra# @ut unless your dealing "ith a very unusual plat)or#, there is a gcc co#piler )or your syste# @ut there is one pro,le# "ith this syste# ;t is possi,le to o#it a )ield ;) you do it gets a de)ault value 002 @ut "hat happens i) you accidentally o#it a value ;t gets assigned a de)ault and "ithout "arning unless you tell gcc to "arn you !he option N-:issingN,ieldNinitiali<ers tells gcc that you "ant to speci)y every )ield "hen you initialiFe ;) you don5t a "arning "ill ,e issued

Hack 3+: Checkin* print, st!le 7r*%ments Lists


The Problem: (ou5ve "ritten a )unction called log_error "hich uses print, style argu#ents Ho" can you tell gcc to check the argu#ents Kust like it does )or print,S The Hack: .se the __attri#ute__ key"ord to tell gcc "hat to check 'or e&a#ple* $oid log_error&const int le$el) const char* const ,or:at) ===' __attri#ute__&&,or:at&print,) *) ?''' 0(es the dou,le parenthesis are needed 2 !he __attri#ute__&,or:at===' synta& tells gcc to treat the argu#ents to logJerror Kust like print, ;n this case the )unction is like print), the )or#at string is the second 022 argu#ent to the )unction and the para#eters start "ith position 4 ;) you have "arnings turned on, gcc "ill no" check the para#eter lists o) any call to log_error to see i) the para#eters #atch the )or#at ote: (ou #ay "ish to put the )ollo"ing lines in your code i) you "ish to co#pile using ,oth gcc and nonCgcc co#pilers Page 1>? Copyright 2008, Steve Oualline

C++ Hackers Guide Ji,nde, ".. Jde,ine __attri#ute__&x' Jendi, /* ".. */ /* Nothing */

Steve Oualline

Hack 3.: 'ackin* str%ct%res


See Hack 11A

Hack 3/: Creatin* #%nctions Who6s Ret%rn Sho%ldn6t -e I*nored


The Problem: So#e )unctions return a value that never should ,e ignored 'or e&a#ple, there is no reason that anyone "ould "ant to call mallo; and ignore the results ;s there any "ay to )orce people to use the return value o) a )unctionS The Hack: Hackers don5t try to )orce people to do things ;nstead they use persuasion Peer pressure can ,e a great #otivator "hen it co#es to getting people to do things right ;n this case "e can #ake things easier ,y #aking use o) the g++ co#piler5s __att(i#ute__ )eature Setting the ?a(n_unused_(esult attri,ute causes the co#piler to issue a "arning "hen the return value o) the )unction is ignored Here5s a short e&a#ple* Jinclude C:alloc=hH Jinclude CcassertH $oid* :%_:alloc&si<e_t si<e' __attri#ute__&&warn_unused_result''; $oid* :%_:alloc&si<e_t si<e' K $oid* ptr = :alloc&si<e'; assert&ptr R= N2 '; return &ptr'; L Go" let5s use this )unction O) course "e5ll use it "rong and Kust thro" the result a"ay creating a #e#ory leak Gor#ally this "ould ,e a pro,le#* int :ain&' K // Pe:or% lea8 :%_:alloc&FF'; Page 1>A Copyright 2008, Steve Oualline

C++ Hackers Guide return &;'; L

Steve Oualline

@ut since "e used __att(i#ute__**?a(n_unused_(esult++ the co#piler "ill co#plain a,out this code* result=cpp: In ,unction aint :ain&'': result=cpp:(E: warning: ignoring return $alue o, a$oid* :%_:alloc&si<e_t'') declared with attri#ute warn_unused_result

Hack 32: Creatin* #%nctions Which =e1er Ret%rn


The Problem: 6e5ve created a )unction called die "hich prints an error #essage and a,orts the progra# (et "hen "e use it the co#piler keeps giving us "arnings 'or e&a#ple* Jinclude Ciostrea:H $oid die&const char* const :sg' K std::cerr CC 97I!: 9 CC :sg CC std::endl; exit&A'; L int co:pute_area&int width) int height' K int area = width * height; i, &area H= ;' return &area'; die&9I:possi#le area9'; L !he pro,le# is that the co#piler keeps co#plaining a,out this code* die=cpp: In ,unction aint co:pute_area&int) int'': die=cpp:(F: warning: control reaches end o, nonN$oid ,unction The Hack: .se the g++ no(etu(n attri,ute 'or e&a#ple* $oid die&const char* const :sg' __attri#ute__&&noreturn'';

Page 1>B

Copyright 2008, Steve Oualline

C++ Hackers Guide $oid die&const char* const :sg' K // === ,unction #od%

Steve Oualline

!his tells g++ that the )unction never returns !he )unctions a#o(t and e2it have this option set Since "e5ve told g++ that die "ill never return, the co#piler "ill no longer )uss "hen co#piling the previous e&a#ple ;) "e turn on the unreacha,le code "arning 0-Wun(ea;Aa#le-;ode2 the co#piler "ill )uss i) "e try and put code a)ter the die call as it should 'or e&a#ple* Jinclude Ciostrea:H $oid die&const char* const :sg' __attri#ute__&&noreturn''; $oid die&const char* const :sg' K std::cerr CC 97I!: 9 CC :sg CC std::endl; exit&A'; L int co:pute_area&int width) int height' K int area = width * height; i, &area H= ;' return &area'; die&9I:possi#le area9'; return &;'; // 0eturn a de,ault $alue L 6hen co#piled "e get the error* gMM N-unreacha#leNcode N-all Nc die=cpp die=cpp: In ,unction aint co:pute_area&int) int'': die=cpp:(A: warning: will ne$er #e executed !his should give the progra##er "ho added the de)ault return value an idea that #ay,e his code is not going to do "hat he e&pected ;t5s al"ays good "hen the co#piler "arns you a,out strange code and as hackers "e "ant to use the co#pilers code checking to #a&i#u# advantage !he __att(i#ute__ hacks let us do Kust that

Page 1>8

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 33: Usin* the GCC Heap Memor! Checkin* #%nctions to Locate Errors
The Problem: 8e#ory corruption ;5# not going to go into details ;) you5re an e&perienced progra##er, you5ve gone through your share o) horri,le #e#ory pro,le#s The 'olution: .se the GG. C li,rary 0gli,c2 #e#ory checking )unctions to help locate pro,le#s !o turn on the #e#ory checking )unctions you need to put the )ollo"ing code in your progra#* Jinclude C:chec8=hH // ==== int :ain&' K :chec8_pedantic&N2

';

!he mem;Ae;5_pedanti; call #ust occur ,e)ore any allocations are done in order to turn on #e#ory checking !he argu#ent is a pointer to a )unction "hich is called "hen an error is detected ;) this para#eter is %4BB then the a de)ault )unction is used !his )unction prints an error and a,orts the progra# !he mem;Ae;5_pedanti; )unction causes the #e#ory allocation )unctions to put sentential at the start and end o) each allocated ,lock :ver ti#e you call mallo;, f(ee, or other #e#ory allocation )unction all these sentential "ill ,e checked 6hen a pro,le# is detected the progra# "ill a,ort 'or e&a#ple* Jinclude C:alloc=hH Jinclude C:chec8=hH int :ain&' K :chec8_pedantic&N2 '; char* ptr = &char*':alloc&(;'; ptrT(;U = 'S'; ,ree&ptr'; return&;'; Page 1>7 Copyright 2008, Steve Oualline

C++ Hackers Guide L 6hen run this progra# prints* :e:or% clo##ered past end o, allocated #loc8

Steve Oualline

!he m;Ae;5_pedanti; per)or#s a consistency check every ti#e #e#ory is allocated or )reed :very #e#ory ,lock is checked %s a result your progra# "ill run slo"er than nor#al !here is a )aster #e#ory check )unction, m;Ae;5 ;t turns on pointer checking only )or the pointer ,eing allocated, reallocated, or )reed (ou can )orce the syste# to check all the #e#ory pointers ,y calling

m;Ae;5_;Ae;5_all
% single pointer can ,e checked ,y the mp(o#e )unction %l#ost all o) these )unctions are docu#ented in the gli,c docu#entation 0.se the co##and in)o gli,c on #ost $inu& distri,utions 2 !he one e&ception is m;Ae;5_pedanti; ;t5s not #entioned in the docu#entation at all Ho"ever it is #entioned in the header )ile 0#check h2 So another lesson "e can learn )ro# this hack is to al"ays take a look at the header )iles to see i) "e can )ind hidden treasure

Hack 155: )racin* Memor! Usa*e


The Problem* 8e#ory leaks 0%nd it5s not )easi,le to use valgrind Q See Hack >1 2 The 'olution* .se the mt(a;e )unction to trace all #e#ory allocations and deallocations ;n order to start #e#ory allocation logging you #ust call the mt(a;e )unction (ou #ust call the munt(a;e )unction to )inish #e#ory tracing !he trace in)or#ation "ill ,e placed in a )ile speci)ied ,y the 9:BB$._T,:.environ#ent varia,le Here5s a s#all progra# to test out this syste#* Jinclude C:alloc=hH Jinclude C:chec8=hH int :ain&' K :trace&';

Page 1?0

Copyright 2008, Steve Oualline

C++ Hackers Guide char* dataT(;U; ,or &int i = ;; i C (;; MMi' K dataTiU = &char*':alloc&(;'; L ,or &int i = (; i C ]; MMi' K ,ree&dataTiU'; L :untrace&'; return &;'; L !his progra# is run "ith the co##and* ^ e2po(t 9:BB$._T,:.-Cmt(a;e!log ^ !Dlea5

Steve Oualline

!he result is a )ile giving us a history o) our heap allocations and )rees*
= Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z = 6tart lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;DcU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU lea8:T;xA;]#;aEU !nd M M M M M M M M M M N N N N N N N N ;xA;##?#; ;xA;##?c; ;xA;##?d; ;xA;##?e; ;xA;##?,; ;xA;##B;; ;xA;##B(; ;xA;##B*; ;xA;##B?; ;xA;##BB; ;xA;##?c; ;xA;##?d; ;xA;##?e; ;xA;##?,; ;xA;##B;; ;xA;##B(; ;xA;##B*; ;xA;##B?; ;xa ;xa ;xa ;xa ;xa ;xa ;xa ;xa ;xa ;xa

Go" all "e have to do is to #atch up the mallo; calls 0denoted ,y the + lines2 and the f(ee calls 0denoted ,y the Q lines2 %ny mallo; "ithout a #atching f(ee is a #e#ory leak 'ortunately "e don5t have to hand #atch !he progra# #trace 0distri,uted "ith gli,c2 "ill do the "ork )or you %ll you have to do is )eed it the na#e o) your e&ecuta,le and log )ile* ^ mt(a;e lea5 mt(a;e!log Pe:or% not ,reed: Page 1?1 Copyright 2008, Steve Oualline

C++ Hackers Guide NNNNNNNNNNNNNNNNN Address 6i<e ;x;A;##?#; ;xa ;x;A;##BB; ;xa .aller at /hac8/lea8=cpp:(; at /hac8/lea8=cpp:(;

Steve Oualline

!here is one li#itation on the mt(a;e )unction ;t doesn5t "ork "ell )or ne. and delete 0(ou get a ,eauti)ul trace sho"ing every mallo; and f(ee ,eing generated ,y the standard C++ li,rary 2 So ,e a"are o) it5s li#itations !he #e#ory tracking and consistency checking )unctions are not the only #e#ory de,ugging )acilities ,uilt into the gli,c li,rary !here are #any "ays to hook up diagnostic code "ith the #e#ory )unctions (ou can read the docu#entation )or details Ho"ever the ones presented in the last )e" hacks "ith )ind #ost o) the co##on errors you are likely to )ind

Hack 151: Generatin* a -acktrace


The Problem* !he de)ault a,ort )unction used ,y m;Ae;5_pedanti; is so#e"hat #ini#al ;t prints an error #essage telling you that you are hosed ,ut that5s all @asically you kno" that so#ething "ent "rong, no" guess "here The Hack: 9e)ine your o"n #e#ory error handling )unction and then use

#a;5t(a;e to get a call stack so you kno" "here you ca#e )ro#
'irst "e need to tell m;Ae;5_pedanti; that "e "ant to handle the error ourselves* :chec8_pedantic&#ad_:e:'; Go" "hen a #e#ory pro,le# is )ound, the #ad_mem )unction "ill ,e called O) course "e need to de)ine the )unction* static $oid #ad_:e:&enu: :chec8_status status' !he #a;5t(a;e )unction returns the call stack as an array o) pointers ;n order to use this )unction "e #ust )irst allocate an array to hold this data then call the )unction* $oid* #u,,erTPAS_+0A.!U; int stac8_si<e = #ac8trace&#u,,er) si<eo,&#u,,er'/si<eo,&#u,,erT;U'';

Page 1?2

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!his gives us a set o) pointers, "hich is not use)ul "hen it co#es to )inding out "here "e are ;t "ould ,e nice to turn this list into so#ething printa,le "ith sy#,ols 'ortunately there5s a )unction to do that called #a;5t(a;e_s>m#ols ;t returns a array o) character pointers containing hu#an reada,le 0#ostly2 version o) our pointers "ith so#e sy#,olic in)or#ation char** stac8_s%: = #ac8trace_s%:#ols& #u,,er) stac8_si<e'; Go" all "e have to do is print the results* std::cout CC 96tac8 trace 9 CC std::endl; ,or &int i = ;; i C stac8_si<e; MMi' K std::cout CC stac8_s%:TiU CC std::endl; L !here5s one #ore thing "e have to do and that is a,ort the progra# 06ith #e#ory corrupt there5s not a "hole lot "e can do at this point 2 So the last line o) our )unction is* a#ort&'; later !he a#o(t call "as chosen ,ecause it creates a core du#p "e can analyFe % typical run o) this progra# produces the results* 6tac8 trace trace T;xA;]#BFAU /li#/tls/li#c=so=E T;xB;(]*A,?U trace&__li#c_,reeM;x(D' T;xA;BeA(DU trace T;xA;]#F(;U trace T;xA;]#F*(U trace T;xA;]#F*,U trace T;xA;]#FE?U trace&__li#c_start_:ainM;x(Bc' T;xA;BcAdcU trace&__gxx_personalit%_$;M;xF(' T;xA;BcD;(U A#orted &core du:ped' .n)ortunately the #a;5t(a;e_s>m#ols call can5t see# to )ind the sy#,ols in our progra# 06e co#piled "ith the de,ug option so they should sho" up 2 !here are nu#,er o) "ays around this pro,le# !he si#plest is to run the de,ugger on the e&ecuta,le and the core )ile and use it to display the stack trace !his gives us the a,ility not only to look at the stack trace, ,ut also the source code and the value o) the varia,les at the ti#e o) the core du#p Page 1?4 Copyright 2008, Steve Oualline

C++ Hackers Guide ^ gd# t(a;e ;o(e!E1FG@ "N2 gd# E=?N?=(=(;*:d8 &Pandra8elinux' J === usual startup chatter === .ore was generated #% a=/trace'= 3rogra: ter:inated with signal E) A#orted=

Steve Oualline

J; ;x,,,,eB(; in __ &' &gd#' ?Ae(e J; ;x,,,,eB(; in __ &' J( ;x#,,,,;Ac in __ &' J* ;x;;;;;;;E in __ &' J? ;x;;;;DcdF in __ &' JB ;x;A;A((Ae in raise &sig=E' at ==linux/raise=c:ED JF ;x;A;FDcaD in a#ort &' at a#ort=c:AA JE ;x;A;]#BeF in #ad_:e: &status=P.I!.4_+AI ' at trace=cpp:*A JD ;xB;(]*A,? in :chec8_chec8_all &' ,ro: /li#/tls/li#c=so=E JA ;x;A;BeA(D in __li#c_,ree &:e:=;xE' at :alloc=c:?F;F J] ;x;A;]#F(; in :e:_pro#le: &' at trace=cpp:?E J(; ;x;A;]#F*( in do_part( &' at trace=cpp:B; J(( ;x;A;]#F*, in do_all &' at trace=cpp:B? J(* ;x;A;]#FE? in :ain &' at trace=cpp:B] &gd#' Go" "e can use the nor#al gd, co##ands to e&a#ine the progra# 'or e&a#ple, let5s take a look at the )unction "here the error "as discovered &gd#' list t(a;e!;pp:EH ?( $oid :e:_pro#le:&' ?* K ?? char* ptr = &char*':alloc&(;'; ?B ?F ptrT(;U = 'S'; ?E ,ree&ptr'; ?D L ?A ?] $oid do_part(&' K B; :e:_pro#le:&'; &gd#' ;n this case the error is ,lindingly o,vious and "e re=uire no )urther investigation ;n the real "orld, things #ight no ,e so si#ple and "e #ight have to spend #ore than )ive seconds to )ind the pro,le# @ut at least "e have to tools in place to detect the pro,le# early and analyFe "hat the progra# is doing Page 1?> Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

%nother "ay o) )inding out "here things are in the progra# is the addr2line co##and 0part o) the gli,c package2 ;t translates an address into a line nu#,er in the progra# 'or e&a#ple* ^ add(<line -. -f -e t(a;e 7287F#G17 :e:_pro#le:&' /ho:e/sdo/hac8/trace=cpp:?E !he -. )lag tells addr2line to de#angle C++ sy#,ols !he -f option causes the )unction na#e as "ell as the line to ,e listed !he progra# )ile is speci)ied "ith the -e option and )inally "e have the address to ,e decoded !his )unction is use)ul "hen it5s i#practical to use gd, )or e&a#ple "hen pro,le#s happen in the )ield and the custo#er doesn5t "ant to send you a ,ig core )ile, ,ut is "illing to send you the ,acktrace output Hackers kno" that there5s #ore than one "ay to solve a pro,le# So#eti#es "e have to use the all in order to )ind the one "hat "orks, ,ut )i&ing things in a poor "orking environ#ent, "ith ,ad tools, inco#plete in)or#ation, and lots o) pressure is so#ething hackers do every day

Page 1??

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 13: 'nti-Hacks


!here are s#art people and there are stupid people %nd then there are stupid people "ho think they are s#art ;t is this type o) people "ho can do so#e real da#age, especially "hen they think they are hackers One o) #y early encounters "ith one o) these people occurred "hen ; had to take over )ro# one o) the# and enhance a con)iguration progra# He had designed this think "ith a very clever top level .; ,ased on a very clever second a,stract .; ,ased on another clever layer o) so#ething, and so on )or a,out eight levels o) co#ple&ity %ll undocu#ented o) course ; had a rather interesting conversation "ith the ,oss "here ; told hi# that it "ould take #e ten "eeks to #odi)y the progra#, ,ut only three "eeks to "rite a ne" progra# that did everything the old one did and included the enhance#ents he "aited !he ne" progra# "ould lack the eight level o) a,straction, ,ut it "ould get the Ko, done % good hack is clear and easy to understand Si#ple is al"ays ,etter unless you5re -u,e Gold,erg and #ake a living o)) o) doing things the hard "ay !his chapter is devoted to the hacks that are not really hacks @y using these techni=ues the people "ho produced the# sho" us that they kno" enough not to ,e clever, ,ut to ,e really, really stupid

7nti4Hack 152: Usin* I9de,ine e&ternJ ,or ;aria0le Declarations


The Problem: ;n order to de)ine a glo,al varia,le you have to create an e&tern declaration in the header )ile and a real declaration in the #odule 'or e&a#ple, a typical header 0de,ug h2* extern int de#ug_le$el; and a code )ile 0de,ug cpp2* int de#ug_le$el; Si#ilar declarations have to ,e put in t"o places ;s there a "ay to eli#inate this duplicationS The ,nti2Hack: !hrough clever use o) the preCprocessor you can #ake one header )ile do ,oth declarations

Page 1?A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

(ou start ,y creating a de,ug h )ile that contains the varia,le declarations %ny progra# "hich uses the de,ug #odule should include the header )ile using the state#ent* // Nor:al progra: ,ile such as :ain=cpp // === Jinclude de#ug=h !he #odule de,ug cpp ho"ever uses a clever preCprocessor trick* // 5ile de#ug=cpp // === Jde,ine extern /* */ Jinclude de#ug=h Junde, extern // NN 7/ N/+ 30/"0AP line* extern int de#ug_le$el; ,eco#es* /* */ int de#ug_le$el; thus you5ve #ade one )ile do dou,le duty saving a lot o) typing !here are a )e" #aKor pro,le#s "ith this code 'irst you5ve rede)ined a standard C++ key"ord Go" "hen so#eone looks at a )ile they #ust decide i) the e4tern key"ord really #eans e4tern or does it #ean so#ething else C++ is ,ad enough "hen co#ing to you unedited 8aking key"ords #ean one thing at one point in the progra# and another thing later on #akes the progra# ten ti#es harder to de,ug Go" suppose an unsuspecting progra##er co#es across the de,ug h )ile and decided that he "ants to add a )unction to it "hich uses ;1O strea#s 'or e&a#ple* extern $oid set_output_,ile&std::ostrea:> out_,ile'; Our de,ug h )ile no" looks like* // de#ug=h &inco:plete' extern int de#ug_le$el; extern $oid set_output_,ile&std::ostrea:> out_,ile'; I4! +II6 RRR NN

!he &define state#ent #ake the e4tern key"ord disappear So no" the

Page 1?B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ecause "e are good progra##ers "e "ant to )ollo" the rules that every header )ile should ,ring any header )ile that it needs to do its "ork ;n this case "e re)erence std::ostrea: so "e need the )strea# header )ile* // de#ug=h Jinclude C,strea:H extern int de#ug_le$el; extern $oid set_output_,ile&std::ostrea:> out_,ile'; Guess "hat %ll the e4tern declarations in )strea# have ,een edited and their e4tern re#oved !he progra# is no" ,roken So this hack prevents the progra##er )ro# )ollo"ing good coding guidelines and #aking a header )ile sel) su))icient ;t gets "orse % good progra##er "ould look at de,ug h and see that Jinclude C,strea:H is #issing O) course ,eing a good progra##er he "ants to #ake things right so he adds this line 0Got kno"ing o) course that the de,ug cpp contains the e4tern antiChack 2 Go" "hen this occurs the good progra##er ,y )ollo"ing good progra##ing practices had Kust ,roken the progra# in strange and #ysterious "ays Suddenly "hen he links in the de,ug #odule he gets duplicate de)ined sy#,ols )or thing in the )strea# #odule % close inspection o) the source code "ill not )ind the progra# !he )strea# header )ile is a syste# )ile ;t5s supposed to ,e correct @esides i) there is a pro,le# in it, the pro,le# "ill sho" up in lots o) progra#s So it5s /o,vious3 that the pro,le# is not )strea# @ut it is, sort o) @ecause the &define rede)ined the C++ language itsel), )strea# has ,een re"ritten and no" contains errors

This anti2hack breaks .orking code in a .ay that is difficult to locate6 *o not use it6
!here are a nu#,er o) other pro,le#s "ith this hack* it doesn5t allo" you to locate varia,le de)initions near the code that uses the#, it doesn5t let you initialiFe glo,al varia,les, and it greatly li#its "hat you can put in a header )ile @ut there are #inor "hen co#pared to the da#age it does ,ecause it rede)ines the C++ language

7nti4Hack 153: Use > AcommaB to Foin statements


The Problem: (ou "ant your code to ,e as co#pact as possi,le and curly ,races use too #any characters !here #ust ,e a "ay o) #aking your code #ore co#pact Page 1?8 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The ,nti2Hack: .se , 0co##a2 to Koin state#ents 'or e&a#ple, instead o) "riting* i, &,lag' K do_part_a&'; a_done = true; L you can do the sa#e thing "ithout the curly ,races* i, &,lag' do_part_a&') a_done = true; !his saves us t"o lines and gets rid o) t"o character 0the curly ,races2 (ou can get even #ore creative "ith for loops* ,or &cur_ptr = ,irst) count = ;; cur_ptr R= N2 cur_ptr = cur_ptrNHnext) MMcount'; ;

!he for loop "e5ve Kust de)ined counts the nu#,er o) ite#s in a linked list and through creative use o) the , 0co##a2 operator "e5ve eli#inated any code ,e)ore the for and inside the ,ody o) the for %s you can see the , 0co##a2 operator is a very po"er)ul tool )or #aking your code very co#pact @ut "hy "ould you ever "ant to do such a thingS Co#pact code #ay have ,een use)ul in the )irst days o) co#puting "hen storage cost several dollars a ,yte, ,ut today you can pick up a 1288 .S@ !hu#, drive at a convenience store 8aking the code #ore co#pact o,scures the logic and #ake the progra# #ore di))icult to read !hus such code is #ore prone to errors and the errors are #ore di))icult to )ind "hen they occur 6hen you use this hack you do not sho" ho" clever a progra##er you are :&perienced hackers already kno" a,out this trick !hey are Kust #ature enough not to use it

7nti4Hack 15(: i, AstrcmpAa>0BB


The Problem: (ou don5t "ant to put /unnecessary3 operators in your code, especially "hen using st(;mp The ,nti2hack: .se the return value o) st(;mp ,are 'or e&a#ple* i, &strc:p&na:e) 8e%_na:e'' K do_special_stu,,&'; L Page 1?7 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he logic o) this code is si#ple and easy to understand Q and e&tre#ely #isleading Luestion* ;s the )unction do_special_stu,, e&ecuted "hen na:e is a 8e%_na:e or nonCkey peopleS -e#e#,er st(;mp returns 0 "hen the strings are e=ual So you5re only special i) you are not the key person !he code is #isleading ,ecause #ost si#ilar )unctions "ill return a true 1 )alse value, the true ,eing the positive case ;n other "ords a i) st(;mp )ollo"ed the rules, it "ould return true o) e=ual and )alse )or not e=ual !he )ollo"ing code is O<* i, &strings_are_sa:e&na:e) 8e%_na:e'' K do_8e%_stu,,&'; L ;n this case the logic o) the progra# and the inititation o) the progra##er reading the code "ill #atch and con)usion is avoided @ut "ith i, &strc:p&na:e) 8e%_na:e'' K the logic o) the co#puter clash "ith "hat anyone reading the code e&pects and you get con)usion One o) the goals o) a good hacker should ,e clarity %)ter all ho" can you sho" the "orld ho" good a hacker you are i) no one understands you "ork !he strcmp code can ,e ,etter "ritten as* // strc:p return $alue ,or eYual strings= static const int 6+0.P3_6AP! = ;; // .hec8 ,or a$erage &nonN8e%' users and process // their special reYuests= i, &strc:p&na:e) 8e%_na:e' R= 6+0.P3_6AP!' K do_special_stu,,&'; L 6hat #akes this code goodS ;t is easy to see )ro# the state#ent* i, &strc:p&na:e) 8e%_na:e' R= 6+0.P3_6AP!' K that the strings are not the sa#e @ut Kust to #ake sure people reading this code understand "hat is going a co##ent has ,een added telling the reader in :nglish "hat is going on 17

17 !he co##ent could ,e #ore precise and e&plicit e&cept this is a #ade up e&a#ple and ; le)t a great deal o) design to the i#agination

Page 1A0

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

7nti4Hack 15+: i, AptrB


The Problem: $ots o) )unctions return a pointer "hen returning a good value and %4BB on error 6e a =uick "ay o) testing )or %4BB The ,nti2Hack* .se i, &ptr' to test to see i) a pointer is %4BB or not 'or e&a#ple* char* ptr = strdup&na:e'; i, &ptr' K process_ptr&'; L else K throw&out_:e:or%_error'; L %gain "e have a progra# techni=ue that leads to e&tre#ely co#pact, terse, and con)using code !he #ain pro,le# "ith code like this is that the pointer is not a ,oolean %s such using it ,are in an if state#ent is #eaningless Our goal as hackers is to create "onder)ul and understanda,le code $eave out short li#it understand 0$eaving "ords out leads to short sentences, ,ut li#its ,ut #akes it di))icult to understand the sentence 2 !yping i, &ptr R= N2 instead o) i, &ptr' takes a )raction o) a second longer, yet can save hours or days o) de,ugging ti#e ,ecause it #akes it easier to read your progra# %s hackers "e "ant people to understand our code, #arvel at it, and then e&tend it Cryptic code does not help us achieve this goal '

7nti4Hack 15.: )he I"hile AAch L *etchABB ML E8#BJ Hack


The Problem: (ou need to read in a stea# o) characters or per)or# so#e other si#ilar operation The ,nti2Hack* .se a co##on C++ design pattern*

Page 1A1

Copyright 2008, Steve Oualline

C++ Hackers Guide // 7on't code li8e this while &ch = getch&' R= !/5' K // === do so:ething L

Steve Oualline

!here are several things "rong "ith this code !he )irst is that it that you have to ,e care)ul can #ake sure that the varia,le ;A is not a char varia,le ;t #ust ,e an int )or the co#parison to "ork !he second pro,le# is that this code does #ultiple operations in a single state#ent %s a result the code is con)using and co#pact ;t is #uch ,etter to have code ver,ose and clear than con)using and co#pact 'inally the line* while &ch = getch&' R= !/5' K is con)using 9o you kno" i) the assign#ent operator 0C2 has higher precedence than not e=ual 0IC2S 'or e&a#ple, "hich o) these t"o state#ent is the e=uivalent o) our .hile loop* while &&ch = getch&'' R= !/5' K while &ch = &getch&' R= !/5'' K !his is one e&a#ple "here Hack 17 co#es in handy !his is a co##on, co#pact "ay o) "riting a .hile loop @ut Kust ,ecause it5s co##on does not #ean it5s good % #ore ver,ose, and easier to understand "ay o) doing the sa#e thing is* // 3lease code li8e this while &true' K int ch = getch&'; i, &ch == !/5' #rea8; // == do so:ething L Go" there are people "ho "ill tell you that this hack is use)ul !hey point out that is is very co##on and ,ecause it5s co##on people recogniFe and understand it %nd ,ecause it5s so co##on and understanda,le people "rite it in ne" code #aking it #ore co##on and )orcing #ore people to recogniFe it and understand it

Page 1A2

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut ulti#ately it5s sloppy pattern and leads to other sloppy coding patterns 'or that reason it should ,e avoided

7nti4Hack 15/: Usin* 9de,ine to 7%*ment the CKK S!nta&


The Problem: !he C++ synta& is not as rich as it could ,e 'or e&a#ple, there5s no single state#ent to iterate through the ite#s o) a linked list The ,nti2Hack: %ug#ent the C++ language ,y using the preCprocessor to de)ine ne" language ele#ents 'or e&a#ple* Jde,ine 5/0_!A.I_I+!P&list' @ ,or &list_ptr cur_ite: = list=,irst; @ cur_ite: =R N2 ; @ cur_ite: = cur_ite:NHnext' !he pro,le# "ith these synta& additions is that you5ve no" change the C++ language to the C++++ language 6hat5s "orse it5s you5re o"n version o) the C++++ language ;t5s di))icult enough )or so#eone to #aster C++ %dding ne" and undocu#ented )eatures to the language #akes things "orse :ven i) so#eone takes the trou,le to docu#ent the# the people #aintaining the progra# have to learn a ne" and uni=ue language %nother pro,le# is that #acros like this tend to hide errors 'or e&a#ple the )ollo"ing "ill result in an in)inite loop or a core du#p* 5/0_!A.I_I+!P&na:e_list' std::cout CC cur_ite:NHna:e CC std::endl; ;t5s di))icult to spot the error ,ecause the #istake is hidden inside the

J$,_-:.H_IT-9 #acro 'or readers o) this ,ook the #istake is so#e"hat easy
to spot ,ecause all you have to do to )ind the #acro de)inition is to look ,ack to the previous code e&a#ple ;n real li)e things are #uch "orse !he #acro de)inition is usually hidden in a header )ile and you have to go hunting )or it ;n general it5s ,etter to "rite code "ho5s synta& is visi,le and standard !hat let5s the people "ho co#e a)ter you understand your "ork so that they can i#prove and enhance it

7nti4Hack 152: Usin* -EGI= and E=D Instead o, N and O


The Problem: !he curly ,races K and L are terse and cryptic @esides they look nothing like "hat you see in %$GO$ progra##ing

Page 1A4

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The ,nti2Hack: .se 6define to de)ine a set o) #acros that allo" you to #ake C code look like %$OG$CA8 Here5s a s#all sa#ple* Jde,ine 1!"IN K Jde,ine !N7 L Jde,ine Jde,ine Jde,ine Jde,ine I5 +I!N ! 6! !N7I5 i, & ' K L else K L

!he code looks like* -II ! &s%ste:_read%&'' 1!"IN int success = process_c:d&'; I5 success +I!N good&'; ! 6! #ad&'; !N7I5 !N7 !his #akes things si#ple and easy to understand i) you5re an %$GO$CA8 progra##er, it #akes things ne&t to i#possi,le i) you5re a C progra##er 8ost progra##ers "hen )aced "ith this sort o) code, curse, then use the preCprocessor to re#ove the #acros and get ,ack to the underlying C code !his hack is o) historical interest ,ecause the original @orne shell "as "ritten this "ay 'ortunately it "as =uickly replaced ,y a C version #uch to the relie) o) all the people "ho had to #aintain this progra#

7nti4Hack 153: ;aria0le 7r*%ment Lists


The Problem: (ou have )unction "hich takes a lot o) di))erent para#eters Speci)ying the# as traditional argu#ents is i#practical So "hat do you doS The ,nti2Hack: .se the varia,le argu#ent list )eature o) C++ to pass in a variety o) ague#ents 'or e&a#ple, let5s suppose "e are dra"ing a ,o& 6e can speci)y a "idth, height, line "idth, color, and other ite#s %ll o) these are optional, i) "e don5t speci)y one a de)ault is used Page 1A> Copyright 2008, Steve Oualline

C++ Hackers Guide Here5s a typical call to our d(a?_#o2 )unction* draw_#ox&1/S_-I7+I) F) 1/S_I!I"I+) ?) N2 ;n this case the N2 ';

Steve Oualline

is used to indicate the end o) the argu#ent list

!his concept can ,e e&panded even )urther Suppose this ,o& contains a list o) "ords Go" "e can do the )ollo"ing* draw_#ox&1/S_-I7+I) F) 1/S_-/076) alpha) #eta) N2 1/S_I!I"I+) ?) N2 '; )

So the "ord list 01/S_-/0762 no" takes a varia,le list o) "ords as it5s para#eter So "e have varia,le para#eter lists in varia,le para#eter lists !his is e&tre#ely cleverN !his is also e&tre#ely dangerous and stupid 'irst o) all this co#pletely de)eats the C++ type checking #echanis# ;n this e&a#ple, 1/S_-I7+I is supposed to ,e )ollo"ed ,y an int @ut "hat i) "e )ollo" it "ith a string draw_#ox&1/S_-I7+I) large) // ==== !he co#piler has no "ay o) kno"ing that the "rong type has ,een supplied !he runti#e has no "ay o) telling a pointer )ro# an integer On #ost syste#s a pointer looks like a very large pointer So the result o) this code is a very large ,o& and a very con)used progra##er @ut that5s not the "orst 6hat happens i) you leave out a N2 S ;) you leave out the ter#inating N2 , the )unction has no "ay o) telling "here the end o) the argu#ent list is 6hat "ill happen is that it "ill go through the argu#ents and look )or a N2 to stop on Got )inding one it "ill continue on using "hatever is store on the stack are argu#ents, until ,y accident it )inds a N2 Or crashes, or so#ething else evil happens ;n any case the result is une&pected and di))icult to diagnose @ecause this syste# de)eats so #any o) the C++ sa)ety checks it should ,e avoided !here are lots o) other "ays o) passing in large nu#,er o) argu#ents "hich provide ,oth )le&i,ility and sa)ety 0'or e&a#ple see Hack > 2 .se one the# instead

Page 1A?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

7nti4Hack 115: 8pa$%e Handles


The Problem: (ou don5t "ant to reveal your i#ple#entation to the user %)ter all he doesn5t need to kno" "hat5s going on inside your code, only ho" to call it The ,nti2Hack* Give the user opa=ue handles to "ork "ith ;n other "ords cast i#ple#entation dependent in)or#ation into so#ething like a oidM or sAo(t int that the user can5t play "ith 'or e&a#ple* t%pede, short int ,ont_handle; t%pede, short int window_handle; ,ont_handle the_,ont = .reate5ont&.ourier) (;'; window_handle the_window = .reate-indow&(;;) ?;;'; 7raw+ext&the_,ont) the_window) Iello -orld) ?;) ?;'; Go" so#e people #ight ask /6hat5s "rong "ith thisS3 %)ter all the user doesn5t need to kno" the details o) "hat #akes up a )ont or a "indo" @y giving hi# an opa=ue type "e hide all this in)or#ation )ro# hi# !he pro,le# is that the in)or#ation is also hidden )ro# the co#piler !here is a,solutely no "ay that the co#piler can tell the di))erent ,et"een a )ont handle and a "indo" handle ;n our e&a#ple the 7raw+ext )unction takes a "indo" handle and )ont handle as its )irst t"o argu#ents ;n that orderN ;n the sa#e sa#ple code a,ove the order is s"itched and there is nothing the co#piler can do to discover the error ;t is possi,le to create type checked opa=ue handles "hich "hich hide the i#ple#entation )ro# the user and still allo" )or co#pile ti#e checking !hese are descri,ed in Hack 41

7nti4Hack 111: Microso,t AH%n*arianB =otation


The Problem: ;t5s i#possi,le to tell the type o) a varia,le Kust )ro# looking at the na#e 'or e&a#ple is #ox_si<e a )loating point nu#,er, an integer, or a structureS The ,nti2Hack: 8icroso)t Gotation

Page 1AA

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

8icroso)t Gotation 0also kno"n as Hungarian Gotation202 is a na#ing syste# "here each varia,le is pre)i&ed "ith type in)or#ation 'or e&a#ple integers ,egin "ith /i3 and )loating point varia,les ,egin "ith /)3 Short integers ,egin /si3 as in si6i<e .nless the short integer is a handle to so#ething, then the /h3 notation kicks in 'or e&a#ple, h,.urrent5ont is a )ont handle O) course so#e people ,elieve that /h3 is too cryptic so they use /hndl3 as hndl.urrent5ont, ,ut this can lead to con)usion as the sa#e pre)i& can ,e used )or )ont handles, "indo" handles, and all the other #any other handles you have to deal "ith in 8icroso)t "indo"s !here are a nu#,er o) pro,le#s "ith this syste# !he )irst is that the "hole idea o) having a co#piler and a high level language is to hide the details o) the i#ple#entation )ro# you Putting this ,ar) on the ,eginning o) each varia,le gives you in)or#ation that you really don5t care a,out !he co#piler needs to kno" detailed type in)or#ation on every varia,le, you do not !he second pro,le# is that there is no standard list o) pre)i& characters 8any people invent their o"n leaving you to guess "hat the di))erence ,et"een ps<Na:e and s<Na:e is !he ans"er is that the )irst is a pointer to a string ending in a Fero character 0i#ple#ented ,y char72 and the second is a string ending in a Fero character 0i#ple#ented ,y char72 ;n other "ords, there is no di))erence 'inally there is the pro,le# o) )le&i,ility and progra# updates Suppose you have i#ple#ented an address ,ook and address is stored in a structure 0stAddress2 (ou i#prove the progra# and replace the structure "ith a class 0cAddress2 %re you going to go through your entire progra# and update the pre)i& o) every address varia,le in itS ;) you do it5s a lot o) "ork 0Got good 2 ;) you don5t you no" have varia,les "hich use an incorrect pre)i& 0Eery not good 2 !his is a loose and loose "orse situation (ou should "rite varia,le na#es using as clear as :nglish 0or "hatever your native language is2 as possi,le $eave type in)or#ation to the co#piler 9on5t #ess up good "ords "ith rando# ,ar) Progra#s are o,scure enough "ithout using notation syste#s "hich o,scure the# #ore "hile adding no value to the progra#

20 !he Hungarians are nice people and should ,e associated "ith such a ,ad hack So that5s "hy the ter# 8icroso)t Gotation is used here even though the ter# Hungarian Gotation is #ore co##only used

Page 1AB

Copyright 2008, Steve Oualline

C++ Hackers Guide Microsoft otation for (nglish

Steve Oualline

Over the years C and C++ progra##ers have devised #any "ays o) #aking their "riting clearer %s a result progra# are #uch #ore reada,le than ever ,e)ore ;5ve o)ten "ondered i) the lessons learned ,y progra##ing could ,e applied to :nglish as "ell !ake 8icroso)t notation 0aka Hungarian notation2 )or e&a#ple ;t puts a pre)i& on each varia,le na#e telling us "hat the type o) the varia,le 6ouldn5t :nglish ,e #uch clearer i) "e identi)ied each ver, "ith UvU, each noun "ith UnU and so on p%)ter av%ll a8any n:nglish n6ords vCan vHave a8ore c!han nOne n8eaning p'or n:&a#ple U#allU v;s pr@oth a% nEer, c%nd a% nGoun p6ith pnOur aGe" nGotation p(ou vCan v6rite nSo#ething a$ike, Ua!here v6as aSuch a% nCro"d p%t ar!he n8all a!hat pn6e v6ere v8alledU c%nd nPeople vCan a:asily v.nderstand p(ou

Page 1A8

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 11: )mbedded Programming Hacks


!he nu#,er o) co#puters is e&ploding !he are no" in phones, "ashing #achines, televisions, toasters, and "atches 21 Progra##ing )or these nonC standard plat)or#s can ,e a real challenge ; got #y )irst progra##ing Ko, "hile ; "as in high school !he ,oss told, /(ou are creating the e#,edded so)t"are )or the Ca#sco 6aterKet ; cutter 3 /Great,3 ; said /6here5s the #achineS3 /(ou see these ,o&es,3 he replied pointing around the roo# ;ndeed there "as a #oderately large stack o) ,o&es against one one /!hey contain the parts "e5re going to ,uild it out o) 3 /Great,3 ; said, /6here5s the hard"are docu#entation 3 /6e5re still in the process o) designing the hard"are %s soon as "e get the prototype done, "e5ll start "riting the docu#entation 3 /6hat a,out the ;1O controller docu#entationS3 /So#e o) the# are o)) the shel), and ; can get you docu#entation )or those @ut there are a couple that "e are #aking ourselves and they are still ,eing designed (ou5ll have to "ait )or in)or#ation on those the design is not solid yet 3 !he Ko, turned out to ,e a very interesting challenge )or all involved 'or #y part ; learned ho" to "rite very )le&i,le code that could ,e easily con)igured to "ork "ith a speci)ic hard"are speci)ication !hat "as #ostly sel) de)ense as getting the hard"are speci)ication "as di))icult, getting it on schedule "as even #ore di))icult, and getting correct in)or#ation Q i#possi,le 0See the )irst hack ,elo" 2 Testing The Water8et !esting the )irst 6aterYet "as a challenge )or all involved ;t "as the )irst production "ater Ket cutter ever #ade so everything "as ne" to all o) us ;n order to get things right "e tested and tuned the #achine )or over a year

21 !here is actually a "atch on "hich you can run $inu&N

Page 1A7

Copyright 2008, Steve Oualline

C++ Hackers Guide 6e had a deal "ith the shoe#aker "ho "as ,uying the #achine He "ould supply us "ith ra" #aterial )or testing and "e "ould give hi# ,ack any pieces cut out during the test process so he could #ake tennis shoes out o) the# Q or so "e thought

Steve Oualline

;n order to get consistent ti#ing results "e did all our ,ench#arking using a single siFe Q 7 right So )or a,out ?CB #onths "e did nothing ,ut cut out a ,atch o) 7 rights, tune the #achine, and ship the cut pieces to the shoe#aker !his "as a very large co#pany "ith #any people "ho turn out hundreds o) thousands o) sho"s each year %)ter )inally getting the #achine tuned and "orking really "ell, "e started the process o) ,reaking it do"n )or ,o&ing and shipping to the custo#er ;t "as then that "e got a call )ro# the )actory )ore#an /%re you the people "ho keep shipping us these 7 rightsS3 6e told hi# "e "ere /'inally ; tracked you people do"n Purchasing had no idea "ho you "ere ,ecause "e never ordered any 7 rights )ro# anyone ; never thought to look at our capitol e=uip#ent ac=uisition group until no" 3 /;s there so#e pro,le# "ith our cut piecesS3 6e "ere a little "orried at this point /Got e&actly, ,ut do you realiFe that you sent us 10,000 nineCrights and no le)tsN322

Hack 112: 7l"a!s ;eri,! the Hard"are Speci,ication


The Problem: Hard"are speci)ications are )re=uently inco#plete, incoherent, inco#prehensi,le, out o) date, or #issing 6hile ; "as "orking on the Ca#sco 6aterYet, ; had to progra# a status panel !his device contained 10 "arning lights ; got the hand"ritten speci)ication )ro# the hard"are guy and decide to test things
22 His e&isting process used a die to cut out a le)t and right at the sa#e ti#e and he had on "ay o) cutting out Kust 7 le)t

Page 1B0

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

$ight 1 "as supposed to ,e /Oil Pressure $o"3 and it "as /-a# )ailure3 $ight 2 "as supposed to ,e /6ater Supply 'ailure3 and it "as /Positioner :rror 3 $ight 4, /9C Po"er 'ailure3 turned out to ,e /Co#pressor 'ailure3 So ; "rote up a nice docu#ent descri,ing "here ho" the syste# "as really "ired and ; handed this to the hard"are guide telling hi# /6oody, the lights are all #i&ed up 3 ; handed hi# the paper, /Here5s ho" they are currently "ired up 3 He took the paper )ro# #y hand and "ent straight to the copy #achine and #ade a copy He then handed #e the copy 0not the original2 and said, /Here5s the ne" speci)ication 3 The Hack: !est early, test o)ten !he )irst thing you should do "hen )aced "ith any ne" piece o) hard"are is to create a short diagnostic progra# that tests out it5s ,asic )unctionality ;t is this progra# "hich lets you discover things like*

Co##ands that don5t )unction as docu#ented @yte order pro,le#s 0"hich o) course are not docu#ented2

9ocu#ent that contains nonCstandard ,it order notation 0;5ve actually read one hard"are #anual that put the least signi)ication ,it on the le)t and the #ost signi)icant on the right 2
Other o#issions, errors, a#,iguities, and pro,le#s "ith the docu#entation

9ealing "ith ne" hard"are )or the )irst ti#e is a di))icult and challenging operation 'ar too #any hard"are people don5t speak so)t"are and don5t kno" ho" to "rite decent docu#entation 0% lot o) so)t"are people are Kust as ,ad "hen it co#es to "riting things do"n 2 @y testing early you can )ind out ho" the hard"are really "orks instead o) ho" it5s supposed to "ork !hat "ay you can "rite a progra# that really does the Ko, instead o) one that supposed to do the Ko,

Hack 113: Use 'orta0le )!pes Which Speci,! E&actl! Ho" Wide :o%r Inte*ers 7re
The Problem: !he C++ does not de)ine ho" #any ,its are in the int type 0Or any other type )or that #atter 2 ;n e#,edded syste#s "e need to kno" the e&act nu#,er o) ,its in order to talk to the hard"are

Page 1B1

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The Hack: 9e)ine porta,le types or use the porta,le types already de)ined )or you !he header )ile Ns>sDt>pes!AO contains a set o) type de)initions provide e&act de)initions )or integer values !he include*

int8_t u_int8_t

int1H_t u_int1H_t

intE<_t u_intE<_t

intH=_t u_intH=_t

@y using these types you are guaranteed that the integers you de)ine have the e&act nu#,er o) ,its you e&pect ;) your syste# doesn5t have these types in a header )ile so#e"here, then de)ine your o"n 0%nd o) course veri)y the# ,e)ore you pu,lish the# 2

Hack 11(: ;eri,! Str%ct%re Si<es


The Problem: !he co#piler5s idea o) the siFe o) a structure #ay ,e di))erent )ro# your idea Here5s a structure de)inition )or the old -;O 8P4 player @ecause the structure #ust e&actly #atch the hard"are speci)ication, the o))set o) each )ield is included in the co##ents !he other thing to note is that this ,lock #ust ,e e&actly ?12 ,ytes long 0again, this nu#,er ca#e )ro# the hard"are speci)ication 2 // director% header struct rio_dir_header K u_int(E_t entr%_count; u_int(E_t #loc8s_a$aila#le; u_int(E_t .ount?*41loc82sed; u_int(E_t #loc8_re:aining; u_int(E_t .ount?*41loc81ad; int?*_t +i:e ast2pdate; u_int(E_t chec8_su:(; u_int(E_t chec8_su:*; char not_used_(T*U; u_int(E_t Version; char not_used_*TF(* N **U; L;

//T;U Nu:#er o, entries //T*U 1loc8s a$aila#le //TBU 1loc8s used //TEU 1loc8s re:aining_ //TAU 1ad #loc8s //T(;U ast ti:e updated //T(BU .hec8su: part ( //T(EU .hec8su: part * //T(AU `un8 //T*;U Version nu:#er //T**U Not used

Page 1B2

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

6hen #usic "as loaded into the -;O player so#e pro,le#s "ere o,served 'irst each ti#e you started to play a song, you got a short ,last o) noise )ollo"ed ,y the song Secondly i) you pressed the )ast )or"ard ,utton, the player "ould Ku#p to the ne&t song So "hat is going on hereS !his pro,le# is especially di))icult to de,ug ,ecause there5s no o))icial docu#entation on the -;O5s inter)ace and there5s a,solutely no "ay o) telling "hat5s going inside the device Ho"ever, you #ay have noticed that "e only included the header de)inition in this ,ook, so that #ay give you so#e idea !he actual pro,le# concerns the "ay that the co#piler lays out structures 6e can discover through testing "hat the real o))sets o) each )ield are !he results are slightly di))erent )ro# the ones "e hand co#puted and put in the co##ents* u_int(E_t #loc8_re:aining; u_int(E_t .ount?*41loc81ad; int?*_t +i:e ast2pdate; u_int(E_t chec8_su:(; //TEU //TAU //T(; // //T(B // 1loc8s re:aining_ 1ad #loc8s (*U ast ti:e updated (EU .hec8su: part (

So ho" co#e the t"o ,yte .ount?*41loc81ad takes up )our ,ytesS !he ans"er is that the co#piler "ants to align 42 ,it values 0+i:e ast2pdate2 on a > ,yte ,oundary !he o))set 10 is not on a > ,yte ,oundary, so the co#piler puts in a couple o) padding ,ytes to #ove the )ield to the ne&t )our ,yte ,oundary So the real structure layout is* u_int(E_t #loc8_re:aining; u_int(E_t .ount?*41loc81ad; u_char hidden_padT*U; int?* +i:e ast2pdate; u_int(E_t chec8_su:(; //TEU 1loc8s re:aining_ //TAU 1ad #loc8s //T(;U Added #% co:piler //T(; // (*U ast ti:e updated //T(B // (EU .hec8su: part (

So our ?12 ,yte structure is really ?1> ,ytes and so#e o) the )ields are in the "rong place 0So#e o) you #ight ask the =uestion /;) ;Ae;5_sum1 and ;Ae;5_sum< are in the "rong place, "hy doesn5t the -;O detect that the checksu#s are incorrect and display an error #essageS Good =uestion, ,ut as a so)t"are hacker you should kno" ,etter than to e&pect consistency, sanity, or co##on sense )ro# a hard"are designer 2 Go" that "e kno" "hat caused this pro,le# "hat can "e do to prevent things like this )ro# occurring in the )utureS Page 1B4 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The Hack: Eeri)y the co#puted siFe o) structure against the actual siFe Si#ply put, our progra# needs the )ollo"ing line* assert&si<eo,&struct rio_dir_header' == F(*'; !his should ,e done )or every data structure shared ,y the so)t"are and the hard"are %s "e have seen the so)t"are5s idea o) "hat goes on in a structure can ,e di))erent )ro# the hard"are5s % possi,le cure )or this pro,le# can ,e )ound in Hack 11A

Hack 11+: ;eri,! 8,,sets When De,inin* the Hard"are Inter,ace


The Problem: !he co#piler can not only pad structures ,ut also #ove )ields around The Hack* Eeri)y the o))set o) every )ield in a structure using the offsetof operator @ack to our previous e&a#ple, let5s veri)y not only the siFe o) the structure ,ut the location o) each )ield as "ell* assert&si<eo,&struct rio_dir_header' == F(*'; assert&o,,seto,&struct rio_dir_header) entr%_count' == ;'; assert&o,,seto,&struct rio_dir_header) #loc8s_a$aila#le' = *'; // ===

Hack 11.: 'ack Str%ct%res )o Eliminate Hidden 'addin*


The Problem: !he co#piler pads things "ithout our per#ission !his scre"s things "hen "e are dealing "ith hard"are The Hack: .se the gcc packed attri,ute to tell gcc to #ake the structure as co#pact as possi,le

Page 1B>

Copyright 2008, Steve Oualline

C++ Hackers Guide 'or e&a#ple*

Steve Oualline

struct rio_dir_header K u_int(E_t entr%_count; //T;U Nu:#er o, entries // ==== L __attri#ute__&&pac8ed''; // Iac8 B( !his is an e&a#ple o) the hacker using the )eatures provided ,y the co#piler to the )ullest ;) you are not using gcc read your co#piler5s docu#entation Chances are they have so#ething si#ilar to the packed attri,ute ;) your co#piler doesn5t support packing o) any type, you5ll have to split the long )ield +i:e ast2pdate into s#aller t"o u_int1H_t )ields that the co#piler "ill pack 6hen encountering a pro,le# like this a good hacker "ill )ind so#e "ay o) going over, under, or through road,locks put up ,y the co#piler

Hack 11/: Understand What the Ho" to Use ItE

e!"ord 1olatile Does and

The Problem: % good co#piler "ill re#ove useless code ;n e#,edded progra##ing so#e code is not as useless as it appears $et5s suppose "e are dealing "ith a serial ;1O controller ;n order to clear the device "e need to unload the three character input ,u))er !he code )or this is* // -on't wor8 // +he de$ice is a :e:or% :apped I// de$ice // Initiali<e the pointer to the input register char* serial_char_in = 7!VI.!_3+0_6!0IA _IN; // === char Xun8_ch; // A Xun8 character Xun8_ch = *serial_char_in; // 0ead one useless character Xun8_ch = *serial_char_in; // .lear second useless char Xun8_ch = *serial_char_in; // +hird character gone // #u,,er now clear So "hat does this code really doS ;t assigns Xun8_ch the top character )ro# the device !his is repeated three ti#es so clear the three character ,u))er

Page 1B?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut the co#piler is s#art ;t looks at this code and says, /!hat )irst assign#ent is useless 6e co#pute the value o) Xun8_ch only to thro" it a"ay ; can eli#inate that line and the progra# "ill act the sa#e 3 So the opti#iFer re"rites the code to look like* char Xun8_ch; // A Xun8 character Xun8_ch = *serial_char_in; // 0ead one useless character ///////////////////////////////////////////////////////// Xun8_ch = *serial_char_in; // .lear second useless char Xun8_ch = *serial_char_in; // +hird character gone Go" it looks at the second line ;t too can ,e eli#inated !he third line can only ,e eli#inated i) Xun8_ch is not used so#e"here later in the progra# ;n this e&a#ple, it5s not so it too is eli#inated !he resulting code is very nicely opti#iFed* char Xun8_ch; // A Xun8 character Xun8_ch = *serial_char_in; // 0ead one useless character ///////////////////////////////////////////////////////// Xun8_ch = *serial_char_in; // .lear second useless char //////////////////////////////////////////////////////// Xun8_ch = *serial_char_in; // +hird character gone /////////////////////////////////////////////////// %nd since Xun8_ch is no" never used, the co#piler can #ake the varia,le disappear and save the stack space it "ould use So the opti#iFer had saved us ti#e ,y cutting out useless instructions and #e#ory ,y eli#inating a useless varia,le 6hat5s "rong "hat thatS !he ans"er is that the progra# no longer )unctions !he device is no longer getting cleared !his is one pro,le# "ith e#,edded progra##ing, the co#piler does not kno" a,out the strange side e))ects that can occur "hen dealing "ith #e#ory #apped ;1O The Hack: .se the volatile key"ord to identi)y #e#ory #apped device and other volatile data !he volatile key"ord tells C++ that a varia,le #ay ,e changed at any ti#e ,y )orces outside the control o) the nor#al progra##ing environ#ent 8ore speci)ically it tells the co#piler that opti#iFer is not allo"ed to change the nu#,er or order o) any access to this varia,le $olatile char* serial_char_in = 7!VI.!_3+0_6!0IA _IN; Go" "e "e e&ecute*

Page 1BA

Copyright 2008, Steve Oualline

C++ Hackers Guide Xun8_ch = *serial_char_in; Xun8_ch = *serial_char_in; Xun8_ch = *serial_char_in;

Steve Oualline // 0ead one useless character // .lear second useless char // +hird character gone

the ;1O device "ill ,e accessed three ti#es and "e "ill clear the device %lert readers #ay notice that "e violated Hack 4 and didn5t use const "here "e should have Since "e don5t "hat to change the pointer, it should ,e #ade const giving us* $olatile char* const serial_char_in = 7!VI.!_3+0_6!0IA _IN; Go" "e have enough advanced key"ords in a single varia,le declaration to identi)y us as a real hacker

Hack 112: Understand What the 8ptimi<er Can Do )o :o%


The Problem: :arly in #y career ; had to "ork "ith a slo" and poorly designed disk controller One o) the things it did "rong as to generate an interrupt in the )ollo"ing #anner* 1 !rigger the interrupt line 2 Set the interrupt ,it in the status registering telling the syste# "hy the interrupt occurred !here "as a pro,le# "ith this syste# ; "as "orking on a )ast processor this "as a slo" disk controller %s such the entire interrupt service routine could co#plete it5s "ork ,et"een the ti#e that the controller per)or#ed step D1 and step D2 .ntil ; )igured this out #y code "as constantly co#plaining o) spurious interrupts and lost interrupts !he pro,le# "ould start the interrupt, ; "ould read the register 0nothing set Q log a spurious interrupt2, the interrupt routine "ould )inish, then the controller "ould set the status ,it indicating "hat ;1O "as availa,le 0O) course ,y this ti#e ;5d dis#issed the interrupt, so the interrupt )or that ;1O "as lost 2 !he /solution3 to this pro,le# "as to add a delay loop to the code at the ,eginning o) the interrupt service routine to give the ;1O controller ti#e to get caught up "ith events /* * -A0NIN": +his is highl% processor dependent */ Page 1BB Copyright 2008, Steve Oualline

C++ Hackers Guide const int 7! AG_./2N+ = (;;; // int result; ,or &int i = ;; i C 7! AG_./2N+; MMi' K result = (* * ?B; L

Steve Oualline oop this :an% ti:es

@ut there are so#e surprises in this code 'irst o) all ho" #any ti#es is the e&ecuted* a2 Iero ti#es ,2 One ti#e c2 100 ti#es ;) you guessed /a3 you5re right Q so#eti#es @ut /,3 and /c3 are also right Q so#eti#es !he pro,le# is that the opti#iFer #ay play all sorts o) ga#es "ith this code !he opti#iFer #ay look at the code and deter#ine that all this code is "aste ti#e so it can ,e eli#inated So the loop "ill e&ecute Fero ti#es ;) (esult is used later in the code, then one trip through the loop is enough and the opti#iFer can drop the other 77 !he GG. C++ co#piler is s#art ;ts opti#iFer says /!his code looks like the useless code you5re )ind in a delay loop, so ;5ll generate the code to go through the loop 100 ti#es 3 !he second =uestion is /Ho" #any ti#es is the #ultiply doneS3 :ven "ithout the opti#iFer the ans"er to this =uestion Fero %ny #odern co#piler kno"s ho" to do constant )olding and "ill evaluate constant e&pressions at co#pile ti#e so they don5t have to ,e co#puted at run ti#e The Hacks: %ctually there are t"o hacks in play here !he )irst is to periodically look at the asse#,ly code to see "hat the co#piler is doing to you !he second is to use the volatile #odi)ier to )orce the co#piler to not opti#iFe your code $et5s take a look at "hat the GG. co#piler does "ith our original delay loop* :o$l ^]]) \eax = F: decl \eax Page 1B8 Copyright 2008, Steve Oualline

C++ Hackers Guide Xns = F

Steve Oualline

So "e have the loop part, ,ut not the #ultiple part !his "ill generate so#e delay ,ut not enough So let5s re"rite the loop using volatile varia,le !he volatile key"ord tells the co#piler that this varia,le is special and to #ake no assu#ptions a,out the saneness o) this varia,le Here5s the ne", i#proved loop* $olatile int result; $olatile int ,( = (*) ,* = ?B; ,or &int i = ;; i C (;;; MMi' K result = ,( * ,*; L Go" )ro# the asse#,ly code "e can see that the #ultiply is actually happing and our delay loop is causing a delay :o$l ^]]) \ecx :o$l ^(*) NA&\e#p' :o$l ^?B) N(*&\e#p' = F: :o$l NA&\e#p') \eax :o$l N(*&\e#p') \edx i:ull \edx) \eax decl \ecx :o$l \eax) NB&\e#p' Xns = F 'inally a good hacker "ould design a short test progra# to test the length o) this delay loop 9elay loops are e&tre#ely di))icult to get right and the processor #ight have so#e surprises in store )or you as "ell ;t should ,e pointed out that hackers avoid "riting delay loops like this as #uch as possi,le Such loops are dangerous to code, nonCporta,le, and a "aste o) CP. resources !hey should only ,e created i) there is there is no other "ay o) getting the progra# to )unction @ut no" at least i) "e5re )orced to use the#, "e can get the# right

Page 1B7

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 113: In Em0edded 'ro*rams> )r! )o Handle Errors Witho%t Stoppin*


The Problem: :#,edded progra#s run in their o"n environ#ent O)ten it5s di))icult i) not i#possi,le )or the user to start and stop services :rrors "hich cause a progra# to stop or crash can easily take do"n the entire device ;) you need a re#inder a,out ho" #uch da#age ,ad error handling can da#age a syste# see the side,ar % -eal Syste# Crash on page >> The Hack: Gever stop %nd even i) you do stop, start right ,ack up again $et5s take a typical progra##ing e&a#ple "here a client #ust connect to a server* .onnection+%pe *the_connect = new .onnection+%pe&./NN!.+I/N_3A0AP!+!06'; !he =uestion is "hat happens "hen the server is not runningS ;n the case o) a typical nonCe#,edded application, you ,ail out "ith an error #essage @asically you tell the user /(ou5ve got a pro,le#, )i& it and then run #e again 3 // +%pical nonNe:#edded code the_connectionNHconnect_to_ser$er&'; i, &the_connection=#ad&'' K std::cerr CC 5A+A !00/0: .ould not connect to ser$er CC std::endl; a#ort&'; L ote: ;n this e&a#ple, the .onnection+%pe class sets an error )lag instead o) thro"ing an e&ception Progra##ing "ise e&ceptions are a cleaner "ay o) doing things @ut they clutter up an e&a#ple "ith e&tra state#ents, so "riting "ise )lags are clearer @ut you should use e&ceptions in real progra##ing Go" in e#,edded progra##ing the user can5t stop and start progra#s So i) a vital progra# dies, the #achine ,eco#es useless to hi# !here5s even a ter# )or this, ver,* /,rick3 as in /6hen he tried to use the "ireless )unction he ,ricked the #achine 3 Since "e don5t "ant our syste#s to dies like this, "e need to #odi)y our progra##ing #ethodology and i) possi,le, never stop Here5s ho" an e#,edded hacker "ould deal "ith connecting to the server*

Page 180

Copyright 2008, Steve Oualline

C++ Hackers Guide // "ood e:#edded code while &(' K the_connectionNHconnect_to_ser$er&'; i, &R &the_connection=#ad&'' #rea8; log_warning& 2na#le connect= -ill retr% in \d seconds) ./NN!.+_7! AG'; sleep&./NN!.+_7! AG'; L

Steve Oualline

So "hat happens i) the server is not readyS ;n this case "e log an error 0to tell so#eone "e had a pro,le#2, then "ait a )e" seconds 0no need to pound the server2, and try again So even i) it takes a "hile )or the server to co#e up, "e "ill eventually connect to it ;) the server never co#es up, the "e never co#e up, ,ut that is not our pro,le# ;t is up to "hoever is handling the server to )igure out a "ay )or it to co#e up, and "hen it does "e5re ready So the ,asic rule is that the progra# "ill keep trying until it succeeds ;t never stops ,ecause it5s al#ost i#possi,le to start it again 0;n ,adly progra##ed syste#s, the only "ay to restart dead processes is to po"er cycle the #achine 2 @ut "hat happens i) your progra# encounters a pro,le# "here retrying is not an option 'or e&a#ple* tr% K char *#u,,er_we_:ust_ha$e = new charT1255!0_6I[!U; // ==== L catch &std::#ad_alloc e' K // __ -hat do we do now_ L !here is no "ay "e can keep retrying the ne. operation until "e get enough #e#ory %)ter all do "e e&pect the user to solve the pro,le# ,y going out, ,uying a #e#ory chip and installing it "hile our progra# keeps runningS Go, in this case "e #ust a,ort !he progra# can no longer )unction @ut in e#,edded progra##ing "e should keep things running "henever possi,le So one hack around the a,ort pro,le# is to #ake sure that i) a progra# does a,ort, "e start it right up again Page 181 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

So "e create a s#all e&ecutive progra# "hich #onitors our #ain progra#* while &(' K s%ste:&:ain_progra:'; log_warning&:ain_progra: stopped= sleep&6!++ !_+IP!'; L

-ill restart=';

%s hackers "e al"ays kno" that there is so#e "ay around /i#possi,le3 restrictions ;n e#,edded syste#s, "e can5t stop, and i) "e do stop, "e don5t stop )or long Go #atter "hat happens, the syste# #ust run

Hack 125: Detectin* Star1ation


The Problem: ;n an e#,edded syste# it5s possi,le )or a high priority process to get stuck and starve all the lo"er priority processes o) CP. po"er Ho" do "e detect such a pro,le# The Hack* .se the co#,ination o) a "atchdog and a lo" priority process to keep the syste# running % "atchdog is a device designed to help keep a syste# running %)ter you set it up it sits there and "aits )or you to ping it every so o)ten ;) )or so#e reason you don5t contact it in a speci)ied ti#e period it "ill reset your syste# !hrough the use o) a "atchdog and a lo" priority task to tickle the "atchdog you can #ake sure that i) you syste# has a pro,le# and locks up, that it "ill then reset and continue Here5s a typical progra# designed to service a "atchdog ti#er* // I, we don't do an%thing ,or F :inutes) re#oot const int -A+.I7/"_+IP! = E; * F; // +ic8le the watchdog e$er% (/* :inute const int 6 !!3_+IP! = ?;; int :ain&' K init_watchdog&'; set_:%_priorit%& /-!6+_3/66I1 !_30I/0I+G'; while &true' K tic8le_watchdog&'; sleep&6 !!3_+IP!'; L Page 182 Copyright 2008, Steve Oualline

C++ Hackers Guide L

Steve Oualline

!he idea is that "atchdog e&pects to have so#eone tickle it every )ive #inutes ;) it doesn5t it "ill get angry and re,oot the syste# 6e are going to tickle is every thirty seconds 0!hat5s #uch less that )ive #inutes2 so "e should ,e sa)e ;) )or so#e reason the syste# gets really ,usy, so ,usy it can5t give our poor tickle process any CP. in )ive #inutes, then the progra# "ill )ail to tickle the "atchdog, the "atchdog "ill get upset and "e5ll re,oot !here are a nu#,er o) hard"are ,ased "atchdog ,oards availa,le as "ell as a so)t"are only kernel driver !hese are all docu#ented in the kernel source in the directory 1usr1src1linu&19ocu#entation1"atchdog ;t should ,e noted that this hack is a solution o) last resort ;t should only ,e used "here the choices are to let the syste# ,e per#anently hung up or reset the syste# Hope)ully the other protections you5ve got ,uilt into the syste# "ill prevent you )ro# ever having to let the "atchdog do its Ko, @ut it a good )ailsa)e against the "orst happening

Page 184

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 12: 4im editing hacks


Ei# is a high po"ered editor ,ased on the old .G;T Ei progra# Ho"ever, it has tre#endously e&tended )eatures ,eyond the Ei co##and set
@ecause Ei# "as #ade ,y progra##ers )or progra##ers %s such it contains a lot o) co##ands designed to #ake a progra##er5s li)e easier !his chapter discusses the #aKor ones "hich include*

Synta& Coloring .sing Ei#5s ,uiltCin #ake syste# %uto#atic ;ndentation Source code e&ploration Eie"ing the $ogic o) $arge 'unctions $og )ile vie"ing

:ven i) you are progra##ing on 8icroso)t 6indo"s you can use Ei# %lthough progra##ing environ#ents like Eisual C++ provide you "ith an editor, the Ei# is )ar superior at editing that their internal editor ote* !his chapter assu#es that you have turned on Ei# e&tended )eatures On .G;T and $inu& syste#s this is done ,y creating a ^1 vi#rc )ile On 8icroso)t 6indo"s this is done ,y de)ault What is 9im

Ei# is a high =uality te&t editor "ho5s one Ko, is to edit te&t )ast ;t is designed )or people, like progra##ers, "ho have to edit a lot o) te&t
One o) the pro,le#s "ith Ei# is its steep learning curve !he #ain cursor #ove#ent keys are h, 3, k, and l ;) you look on a key,oard you5ll see that these keys are the /ho#e3 type positions on the right hand ;n other "ords, they are the )astest and easiest keys )or #ost people to type

Page 18>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

@ut they are totally nonC#ne#onic 0'or e&a#ple, right is l 0lo"er case $2 2 $earning Ei# takes ti#e, ,ut one you do learn the# you can edit =uicker than al#ost any other editor 24

Hack 121: )%rnin* on S!nta& Colorin*


The Problem: !e&t editing using a si#ple #onospaced )ont "ith no color The Hack: !urn on Ei#5s synta& coloring !o turn on synta& coloring in Ei# si#ply e&ecute the co##and* :s%ntax on Go" things such as key"ords, strings, co##ents, and other synta& ele#ents "ill have di))erent colors 0;) you have a ,lackCandC"hite ter#inal, they "ill have di))erent attri,utes such as ,old, underline, ,link, and so on 2 %ctually you usually don5t e&ecute this co##and #anually ;nstead it5s put in your RHO8:1 vi#rc )ile so that it is auto#atically e&ecuted each ti#e Ei# is started

Hack 122: Usin* ;im6s internal make s!stem


The Problem: (ou have to e&it Ei# to ,uild a progra#, then go ,ack into Ei# to )i& the pro,le#s The Hack: .se Ei#5s ::a8e co##and to per)or# the ,uilds !he Ei# ::a8e co##and ,uilds the progra# ,y running the #ake progra# 0On 6indo"s the n#ake co##and is used 2 !o start the ,uild process e&ecute the co##and* ::a8e [arguments] ;) errors "ere generated, they are captured and the editor positions you "here the )irst error occurred !ake a look at a typical :ma5e session 0!ypical :ma5e sessions generate )ar #ore errors and )e"er stupid ones 2 'igure A sho"s the results 'ro# this you can see that you have errors in t"o )iles, #ain c and su, c

24 :#acs users "ill pro,a,ly challenge this state#ent as "ell as people "ith other )avorite editors ;) you are one o) these people you can easily skip this chapter

Page 18?

Copyright 2008, Steve Oualline

C++ Hackers Guide


:R:a8e O > tee /t:p/$i:*(F]F?=err gcc Ng N-all No prog :ain=c su#=c :ain=c: In ,unction a:ain': :ain=c:E: too :an% argu:ents to ,unction ado_su#' :ain=c: At top le$el: :ain=c:(;: parse error #e,ore aU' su#=c: In ,unction asu#': su#=c:?: aX' undeclared &,irst use in this ,unction' su#=c:?: &!ach undeclared identi,ier is reported onl% once su#=c:?: ,or each ,unction it appears in=' su#=c:B: parse error #e,ore aU' su#=c:B: warning: control reaches end o, nonN$oid ,unction :a8e: *** TprogU !rror ( * returned 9:ain=c9 (( ) (((. &? o, (*': too :an% argu:ents to ,unction ado_su#' 3ress 0!+20N or enter co::and to continue

Steve Oualline

'igure A* :make output


6hen you press :nter 0"hat Ei# calls -eturn2, you see the results sho"n in 'igure B int :ain&' K int i=? do_su#&9,oo9'; MMi; return &;'; L L Q &? o, (*': too :an% argu:ents to ,unction do_su#

'igure B* !he )irst error


!he editor has #oved you to the )irst error !his is line A o) #ain c (ou did not need to speci)y the )ile or the line nu#,er, Ei# kne" "here to go auto#atically !he )ollo"ing co##and goes to "here the ne&t error occurs 0see 'igure 82* :cnext

Page 18A

Copyright 2008, Steve Oualline

C++ Hackers Guide int :ain&' K int (=? do_su#&9,oo9'; MMi; return &;'; L L Q &F o, (*': parse error #e,ore aLb

Steve Oualline

'igure 8* :cnext
!he co##and :;p(e ious or :;%e2t goes to the previous error Si#ilarly, the co##and :;last goes to the last error and :;(e?ind goes to the )irst !he :;nfile goes to )irst error #essage )or the ne&t )ile 0see 'igure 72 int su#&int i' K return &i * X' L Q Q Q Q Q Q &D o, (*': aX' undeclared &,irst use in this ,unction'

'igure 7* :cnfile co##and


;) you )orget "hat the current error is, you can display it using the )ollo"ing co##and* :cc ;) you have already run #ake and generated your o"n error )ile, you can tell Ei# a,out it ,y using the :;file error-file co##and 6here errorfile is the na#e o) the output o) the #ake co##and or co#piler ;) the errorfile is not speci)ied, the )ile speci)ied ,y the Pe((o(fileP option is used %nother co##and "hich #ay ,e o) use to you is the :;open co##and ;t opens a ne" "indo" containing a list o) errors and lets you select the error you "ant to e&a#ine ,y #oving to it and pressing Nente(O

Page 18B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'inally the :Aelp co##and can ,e used to get docu#entation on all the co##ands presented here

Hack 123: 7%tomaticall! Indentin* Code


The Problem: ;ndenting C++ progra#s is a chore The Hack: $et Ei# do it auto#atically !he Ei# editor contains a very s#art indentation syste# !o access it all you have to do is turn it on "ith the co##and* :set cindent @y de)ault the indentation siFe is 8 spaces ;) you "ish so#ething di))erent, like )or e&a#ple an indentation siFe o) >, you need to e&ecute this co##and* :set shi,twidth=B %gain, these co##ands are )re=uently put in the RHO8:1 vi#rc )ile so they are e&ecuted every ti#e Ei# starts Go" "hen you type code as you press enter, the progra# "ill ,e indented auto#atically 'igure 10 illustrates ho" P;indentP "orks %uto#atic indent %uto#atic .nindent %uto#atic ;ndent %uto#atic .nindent i, &,lag' do_the_wor8& '; i, &other_,lag' K do_,ile & ' ; process_,ile&'; L

'igure 10* cindent


ote: (ou #ay not "ant to turn on P;indentP )or all types o) )iles ;t "ould really #ess up a te&t )ile !he )ollo"ing co##ands, "hen put in a vi#rc )ile "ill turn on P;indentP )or C and C++ )iles only :,ilet%pe on :autoc:d 5ile+%pe c)cpp :set cindent

Hack 12(: Indentin* E&istin* -locks o, Code


The Problem: (ou are give a legacy progra# "hich has ,een edited so #any ti#es so as to #ake the indentation useless Page 188 Copyright 2008, Steve Oualline

C++ Hackers Guide you

Steve Oualline

The Hack: .se Ei#5s internal indentation )unctionality to do the "ork )or !o indent a ,lock o) te&t using Ei# e&ecute the )ollo"ing co##ands* 1 Position the cursor on the )irst line to ,e indented 2 :&ecute the ' 0upper case /v32 co##and to start /E;S.%$ $;G:3 #ode 4 8ove to the last line to ,e indented using any o) the Ei# #ove#ent co##ands !he ,lock to ,e indented "ill ,e highlighted 0See 'igure 11 2 > :&ecute the Ei# co##and C to indent the highlighted te&t

Page 187

Copyright 2008, Steve Oualline

C++ Hackers Guide Start here // .ode intentionall% indented wrong int do_it&' K i, &toda%' do_toda%&'; Press E do_now&'; 8ove to do_reYuired&'; here do_,inish&'; L int :ain&' K do_it&'; return&;'; L Press C -esult* // .ode intentionall% indented wrong int do_it&' K i, &toda%' do_toda%&'; do_now&'; do_reYuired&'; do_,inish&'; L int :ain&' K do_it&'; return&;'; L

Steve Oualline

'igure 11* ;ndenting Code

Hack 12+: Use ta*s to =a1i*ate the Code


The Problem: (ou5ve "orking on a ,unch o) code you5re not )a#iliar "ith and "ish to go through the code step ,y step (ou5ve co#e to a call to do_the_,unn%_#ird and you "ant to see "hat this )unction does, ,ut you don5t kno" "here it5s de)ined Ho" do navigate through the code e))ective in such cases

Page 170

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The Hack: .se the ctags2> co##and to generate a location )ile 0called tags2 "hich Ei# can use to locate )unction de)initions (ou need to generate the tags )ile ,e)ore you start editing !his is done "ith the co##and ^ ;tags M!;pp M!A Go" "hen you are in Ei# and you "ant to go to a )unction de)inition, you can Ku#p to it ,y using the )ollo"ing co##and* :tag do_tAe_funn>_#i(d !his co##and "ill )ind the )unction even i) it is another )ile !he .T,B-] co##and Ku#ps to the tag o) the "ord that is under the cursor !his #akes it easy to e&plore a tangle o) C++ code Suppose, )or e&a#ple, that you are in the )unction write_#loc8 (ou can see that it calls write_line @ut "hat does write_line doS @y putting the cursor on the call to write_line and typing .T,B-], you Ku#p to the de)inition o) this )unction 0see 'igure 122 !he write_line )unction calls write_char (ou need to )igure out "hat it does So you position the cursor over the call to write_char and press .T,B-] Go" you are at the de)inition o) write_char 0see 'igure 142

2> 8ake sure you get the e&tended version )ro# http*11ctags source)orge net1

Page 171

Copyright 2008, Steve Oualline

C++ Hackers Guide $oid write_#loc8&char line_setTU' K int i; ,or &i = ;; i C N_ IN!6; MMi' write_line&line_setTiU'; L

Steve Oualline

.T,B-] goes to the de)inition o) write_line 0s"itching )iles i) needed2


!he co##and :tag ?(ite_line does the sa#e thing

$oid write_line&char lineTU' .+ K o, w int i; i, n ,or &i = ;; lineT;U R= '@;'' write_char&lineTiU'; L Q 9write_line=c9 E )

'igure 12* !ag Ku#ping "ith CT-L2:


$oid write_char&char ch' K .T,B-] "ith cursor on write_raw&ch'; write_char gets us here L Q 9write_char=c9 B ) BA.

'igure 14* Yu#ping to the write char tag


!he :tags co##and sho"s the list o) the tags that you have traversed through 0see 'igure 1>2

Page 172

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Q :tags J +/ tag 50/P line in ,ile/text ( ( write_#loc8 ( write_#loc8=c * ( write_line F write_#loc8=c ? ( write_char F write_line=c H 3ress 0!+20N or enter co::and to continue

'igure 1>* !he :tags co##and


Go" to go ,ack !he .T,B-T co##and goes the preceding tag !his co##and takes a count argu#ent that indicates ho" #any tags to Ku#p ,ack So, you have gone )or"ard, and no" ,ack $et5s go )or"ard again !he )ollo"ing co##and goes to the tag on the list* :tag (ou can pre)i& it "ith a count and Ku#p )or"ard that #any tags 'or e&a#ple* :?tag 'igure 1? illustrates the various types o) tag navigation

:tag ?(ite_#lo;5 .T,B-] 0on write_line2 .T,B-] 0on write_char2

write_block

write_line

write_char

<.T,B-T

:<tag :tag

.T,B-T

Page 174

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'igure 1?* !ag navigation

Hack 12.: :o% =eed to #ind the Location o, 'roced%re ,or Which :o% 8nl! no" 'art o, the =ame
The Problem: (ou Usort o) U kno" the na#e o) the procedure you "ant to )indS !his is a co##on pro,le# )or 8icroso)t 6indo"s progra##ers ,ecause o) the e&tre#ely inconsistent na#ing convention o) the procedures in the 6indo"s %P; .G;T progra##ers )are no ,etter Only the inconsistency in na#ing conversions is consistent] the only pro,le# is that .G;T likes to leave letters out o) syste# call na#es 0)or e&a#ple, creat2 The Hack: .se the :tag co##and to search )or procedures using a regular e&pression ;) a procedure na#e ,egins "ith D, the :tag co##and assu#es that the na#e is a regular e&pression ;) you "ant to )ind a procedure na#ed Uso#ething "rite so#ething,U )or e&a#ple, you can use the )ollo"ing co##and* :tag /write !his )inds all the procedures "ith the "ord "rite in their na#es and positions the cursor on the )irst one ;) you "ant to )ind all procedures that ,egin "ith read, you need to use the )ollo"ing co##and* :tag /cread ;) you are not sure "hether the procedure is 7o5ile, do_,ile, or 7o_5ile, you can use this co##and* :tag /7o5ile@Odo_,ile@O7o_5ile or :tag /T7dUo_@=T5,Uile !hese co##ands can return #ultiple #atches (ou can get a list o) the tags "ith the )ollo"ing co##and* :tselect name 'igure 1A sho"s the results o) a typical :tsele;t co##and

Page 17>

Copyright 2008, Steve Oualline

C++ Hackers Guide Q

Steve Oualline

J pri 8ind tag ,ile H ( 5 . , write_char write_char=c $oid write_char&char ch' * 5 , write_#loc8 write_#loc8=c $oid write_#loc8&char line_setTU' ? 5 , write_line write_line=c $oid write_line&char lineTU' B 5 , write_raw write_raw=c $oid write_raw&char ch' !nter nr o, choice &C.0H to a#ort':

'igure 1A* :tselect co##and


!he )irst colu#n is the nu#,er o) the tag !he second colu#n is the Priority colu#n !his contains a co#,ination o) three letters ' S ' 'ull #atch 0i) #issing, a caseCignored #atch2 Static tag 0i) #issing, a glo,al tag2 !ag in the current )ile

!he last line o) the :tsele;t co##and gives you a pro#pt that ena,les you to enter the nu#,er o) the tag you "ant Or you can Kust press :nter 0N.,O in Ei# ter#inology2 to leave things alone !he g] co##and does a :tsele;t on the identi)ier under the cursor !he :tjump co##and "orks Kust like the :tsele;t co##and, e&cept i) the selection results in only one ite#, it is auto#atically selected !he g.T,B-] co##and does a :tjump on the "ord under the cursor % nu#,er o) other related co##ands relate to this tag selection set, including the )ollo"ing*

:count tne2t :count tp(e ious :count t%e2t :count t(e?ind :count tlast

Go to the ne&t tag Go to the previous tag Go to the ne&t tag Go to the )irst tag Go to the last tag

'igure 1B sho"s ho" to use these co##ands to navigate ,et"een #atching tags o) a :tag or :tsele;t co##and Page 17? Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

:tag D?(ite :tne2t :tne2t

write_block :tlast :t(e?ind

write_line :tp(e ious :tne2t

write_char

'igure 1B* !ag navigation

Hack 12/: Use :1im*rep to Search ,or ;aria0les or #%nctions


The Problem: (ou "ant to discover every place that a varia,le is used you The Hack: .se Ei#5s internal : img(ep co##and to do the searching )or

!he : img(ep co##and acts #uch like :ma5e ;t runs the e&ternal progra# grep and captures the output !o )ind all occurrences o) the varia,le groundJpoint, )or e&a#ple, you use this co##and*

: img(ep DQNg(ound_pointQOD MMDM!;pp


!he @C===@H tells Ei# to look )or )ull "ords only ground_point is the string you are looking )or 'inally, there is the list o) )iles to search through is all directories 0HH2 and all C++ )iles 0*=cpp2 'igure 18 sho"s the results

Page 17A

Copyright 2008, Steve Oualline

C++ Hackers Guide MMi; return &;'; L L :ain=cpp:F: int i=?; :ain=cpp:D: MMi; su#=cpp:(:int su#&int i' su#=cpp:?: return &i * X' &( o, B': : int i=?; 3ress 0!+20N or enter co::and to continue

Steve Oualline

'igure 18* :vimgrep output


ote: !he grep progra# kno"s nothing a,out C++ synta&, so it "ill )ind ground_point even it occurs inside a string or co##ent (ou can use the :;ne2t, :;p(e ious, and :;; co##ands to page through the list o) #atches %lso :;(e?ind goes to the )irst #atch and :;last to the last 'inally, the )ollo"ing co##and goes to the )irst #atch in the ne&t )ile* :cn,ile

Hack 122: ;ie"in* the Lo*ic o, Lar*e #%nctions


The Problem: (ou5ve got legacy code that looks like* i, &,lag' K start_o,_long_code&'; // ()A?B :ore lines o, code end_o,_long_code&'; L else K return &error_code'; L Ho" do you )igure out the /logic3 o) such a )unctionS The Hack: .se the Ei# )old )eature Start ,y putting the cursor on the )irst line o) the con)using code i, &,lag' K start_o,_long_code&'; // ()A?B :ore lines o, code end_o,_long_code&'; L else K return &error_code'; Page 17B Copyright 2008, Steve Oualline

C++ Hackers Guide L

Steve Oualline

Press ' to start visual line #ode !he line "ill ,e highlighted i, &,lag' K start_o,_long_code&'; // ()A?B :ore lines o, code end_o,_long_code&'; L else K return &error_code'; L Go to the end o) the long code (ou can do several "ays* 1 8ove the cursor using the nor#al cursor #ove#ent co##ands such as j 0do"n2 or D 0search2 2 Go up to the curly ,racket and press R 0)ind #atching ,racket2, then #ove up a line 4 :nter the operator pending co##and i& to select the te&t inside the

KL
6hen you )inish #oving the cursor the lines inside the KL "ill ,e highlighted i, &,lag' K start_o,_long_code&'; // ()A?B :ore lines o, code end_o,_long_code&'; L else K return &error_code'; L Go" enter the co##and F) to /)old3 the highlighted te&t !he 1,84A lines o) code are no" replaced ,y a single line telling you that a )old has ,een placed here i, &,lag' K +--- 1836 lines: start_of_long_code( ! ------------------+ L else K return &error_code'; L !he editor no"s gives you an idea "hat the logic o) the )unction looks like ;) you "ant to see the te&t again, position the cursor on the )old line and type )o Page 178 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!here is a lot going on here, so you #ay "ish to ,ro"se the help te&t !o get help on the co##ands docu#ented e&ecute the )ollo"ing co##ands*

Help Command

Topic
Eisual 8ode 0the highlighting2 8atch OP 0and other things2

:Aelp ' :Aelp R :Aelp )f )o _i&

Select inner ,races 0te&t ,et"een OP2 Create )old -e#ove 0open2 )old

Hack 123: ;ie" Lo*,iles "ith ;im


The Problem: (ou5ve got a log )ile, ,ut it5s 18,4B4 lines too long Ho" do you cut it do"n to siFe The Hack: .se your te&t editor ;t5s an ideal tool )or te&t #anipulation and ,ro"sing $et5s take a look at so#e o) the things you can do "ith the Ei# editor 6e5ll assu#e you5re already )a#iliar "ith the si#ple co##ands like search and cut @ut there are other co##ands "e can use 'or e&a#ple, let5s suppose "e are only interested in lines containing the string /'ra#e Header3 6e can tell Ei# to delete all lines e&cept the ones containing /'ra#e Header3 "ith the )ollo"ing co##ands* 1 Go to the )irst line in the code 0132 2 Start a operation to pipe the te&t through a )ilter co##and !he portion o) the te&t to ,e )iltered that runs )ro# the current cursor location to the end o) the )ile 0I32 Z:&cla#ation Point[Z$etter G[ 4 :nter the )ilter co##and ;n this case "e are using grep to search )or lines so our )ilter co##and is* g(ep PJ(ame Heade(PNente(O %s one string this co##and is* ("R"grep '5ra:e Ieader'CenterH !he result is a log )ile "ith Kust the in)or#ation "e are interested in, and i) "e are lucky Kust the right a#ount o) in)or#ation to )ind the ,ug

Page 177

Copyright 2008, Steve Oualline

C++ Hackers Guide here

Steve Oualline

!here are lots o) "ays o) #anipulating te&t in Ei# 'ar too #any to list

!he co#,ination o) e&tensive logs and a good te&t editor #akes it easy to locate and vie" the in)or#ation "e "ant !his nonCstandard use o) a te&t editor is one "ay a good hacker can think /out o) the ,o&3 and #ake )ull use o) the tools availa,le to hi#

Page 200

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Chapter 1!: Cle+er but (seless


Got all hacks have a practical use So#e hackers invent very clever "ays o) doing things Kust to sho" o)) so#e very clever code so they can have ,ragging rights Got that this is an entirely useless endeavor 'iguring ho" to say e&change the value o) t"o varia,les "ithout using a te#porary re=uires you to kno" a lot a,out so#e o) the #ore o,scure aspects o) the co#puter and o) progra##ing %nd e&peri#enting and learning these skills is one o) the true attri,utes o) a good hacker

Hack 135: #lippin* a ;aria0le -et"een 1 and 2


The Problem: % varia,le ,lag can have the value ( or * ;) it is ( change it to * and i) it is * change it to ( Go" the #ost straight )or"ard "ay o) doing this is* i, &,lag == (' K ,lag = *; L else K ,lag = (; L !he paranoid hacker "ould use a s.itch and check )or out o) range values* // +his is the #est and sa,est solution i, we don't // care a#out speed switch &,lag' K case (: ,lag = *; #rea8; case *: ,lag = (; #rea8; de,ault: assert&,lag is not ( or * == ;'; a#ort&'; // Pa8e sure we stop L !he previous ,it o) code is the pre)erred solution i) "e don5t care a,out speed and "e "ish to ,e ,oth clear and paranoid @ut in this case our goal is to de#onstrate ho" clever "e are and produce a very clever hack

Page 201

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

The Hack: !he varia,le can ,e toggled ,et"een the t"o values "ith one si#ple su,traction state#ent* ,lag = ? V ,lag; (ou can no" take a )e" seconds to veri)y the correctness o) this state#ent !his code )unctions ho"ever it is inco#plete ;) you #ust include clever code in your progra# like this, please please include co##ents telling the people that co#e a)ter you "hat you5ve done // +his cle$er piece o, code ,lips the ,lag $aria#le // #etween the $alues o, ( and *= ,lag = ? V ,lag; !his is al#ost the per)ect hack ;t is clever, it is s#all, it is e&tre#ely )ast, and it is clear 0a)ter the addition o) the co##ent2 Go" i) "e could Kust )ind so#e progra# "e could use it in

Hack 131: S"appin* )"o =%m0ers Witho%t a )emporar!


The Problem: Ho" do you s"ap t"o varia,les "ithout using a te#porary The Hack: .se the )ollo"ing code* $oid swap&int> a) int> #' K a c= #; # c= a; a c= #; L !his is the classic CS201 ans"er @ut as hackers "e are never content to leave things alone @ecause ;5# a hacker ; "anted to see ho" things operate in the real "orld %nd ; discovered another "ay o) s"apping varia,les "ithout using a te#porary* static $oid inline swap&int> a) int> #' K int t:p = a; a = #; # = a; L Go" you #ight "onder ho" ; can clai# that this doesn5t use a te#porary "hen ; declare a te#porary varia,le on the second line o) the )unction !he trick is that ; declared this )unction inline and turned on opti#iFation !his le)t the co#piler )ree to )igure out the ,est "ay o) s"apping the t"o varia,les Page 202 Copyright 2008, Steve Oualline

C++ Hackers Guide like* int :ain&' K int a = (; int # = *; print&a)#'; swap&a)#'; print&a)#'; return&;'; L

Steve Oualline

$et5s take a look at "hat the opti#iFer did )or us !he )irst test code looks

-unning this through the co#piler and taking a look at the asse#,ly code generated "e can see that the co#piler re"rote our #ain )unction* print&a)#'; print&#)a'; !he swap call "as eli#inated co#pletely So not only did the co#piler eli#inate the te#porary, it also eli#inated all the code as "ell (ou can5t get #ore opti#iFed that that ;) "e change our test to )orce the actual s"apping o) the varia,les "e get the )ollo"ing code* :o$ :o$ :o$ :o$ reg() a reg*) # a) reg* #) reg(

Go" registers don5t count as te#porary varia,les 0at least i) ;5# doing the counting2 so again "e have a case "here "e are s"apping the varia,les "ithout a te#porary !his =uestion lets us illustrate several attri,utes o) a true hacker !he )irst is a "illingness to think outside the ,o& %nyone can look up the standard ans"er on the ;nternet @ut only a good hacker "ill ask the =uestion /Hey, "hat "ill happen i) 3 and then per)or# a ,unch o) e&peri#ents ans"ering that =uestion ;) the hacker is really good you )ind yoursel) "ith an ans"er that is surprising and #uch ,etter than the /standard3 ans"er

Page 204

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 132: Re1ersin* the Words In a Strin* Witho%t a )emporar!


The Problem: Ho" do you reverse the "ord in a string "ithout using a te#porary string The 'olution: -everse the string, then go through the string reversing the "ords 'or e&a#ple start "ith the string* Now is the ti:e -everse the entire string* e:it eht si woN !hen reverse the individual "ords* ti:e eht si woN ti:e the is woN ti:e the is Now !urns out that #oving a "ord )ro# one end o) a string to another is a di))icult operation -eversing a string is si#ple So instead o) #oving "ords to their proper place, "e reverse the# in, then reverse the "ord to #ake it co#e out the right "ay round !he code is ,elo"* Jinclude Ciostrea:H Jinclude Cct%pe=hH // "i$en two character pointers) re$erse // the string #etween the: static $oid re$_chars& char* ptr() char* ptr* ' K char t:p; while &ptr( C ptr*' K t:p = *ptr(; *ptr( = *ptr*; *ptr* = t:p; ptr(MM; ptr*NN; Page 20> Copyright 2008, Steve Oualline

C++ Hackers Guide L L // 0e$erse the words in a string // &-ithout a te:porar%' $oid re$erse&char* const str' K // 0e$erse the entire string re$_chars&str) str M strlen&str'N('; // 3ointer to the ,irst character o, a word // to re$erse char* ,irst_ptr = str;

Steve Oualline

// 4eep looping until we run out o, string while &*,irst_ptr R= '@;'' K // Po$e up to the ,irst letter o, the word while &R isalpha&*,irst_ptr'' K i, &*,irst_ptr == '@;'' return; ,irst_ptrMM; L char* last_ptr; // +he last letter o, the word M ( // 5ind last letter ,or &last_ptr = ,irst_ptrM(; isalpha&*last_ptr'; MMlast_ptr' continue; // 0e$erse word re$_chars&,irst_ptr) last_ptrN('; // Po$e to next ,irst_ptr = last_ptr M(; L L Good hackers "ill look ,eyond the i##ediate pro,le# and ask the =uestion /6hy are you doing such a thingS3 ;t #ay ,e that the "ords are ,eing consu#ed ,y so#e sort o) co##and parser "hich needs the# in reverse ;) that5s true, then there5s no reason to reverse the "ords, then ,reak the# apart in the co##and parse Yust #odi)y the co##and parser to ,reak a string apart into "ords in reverse order Great hackers not only are a,le to solve the pro,le# ,e)ore the#, ,ut look ,eyond it and provide solutions that a))ect the ,igger picture

Page 20?

Copyright 2008, Steve Oualline

C++ Hackers Guide )overnment ; The ,nti2Hacker

Steve Oualline

% group o) hackers "ere "orking )or a govern#ent contractor translating a ,unch o) code )ro# one version o) YOE%$ to another "hen they ca#e across this very ,adly "ritten )unction !he )igured that they could re"rite it to ,e ,oth cleaner and #ore e))icient ;n order to #ake sure that their ne" design "orked "ith the e&isting code, they searched the code to )ind every place "here the )unction "as called !hey )ound none Gothing !he )unction "as never called So they "ent to the ,oss and said, /!his )unction is never used, "e can get rid o) it 3 !he ,oss told the# that he kne" the )unction "as never used ;t hadn5t ,een called )or at least three releases @ut ,ecause this "as a govern#ent progra#, the cost o) doing the paper"ork )ar e&ceeded the cost o) paying so#eone to update it

Hack 133: Implementin* a Do%0le Linked List "ith a Sin*le 'ointer


The Problem: Ho" can you i#ple#ent a dou,ly linked list using only a single pointer )or each linkS 0!his =uestion "as originally asked "hen #e#ory cost RRR instead o) _ so at the ti#e it #ade sense 2 The Hack: :&clusive or 0TO-2 the )or"ard and ,ack"ard links and store that value in the pointer* node=lin8 = next_ptr c pre$_ptr; 6hen going through the list in a )or"ard direction, you can reconstruct the pointer to the ne&t node using the pointer to the previous one cur_ptr = ,irst_ptr; pre$_ptr = N2 ; while &cur_node R= N2 ' K // 7o so:ething with the current node Page 20A Copyright 2008, Steve Oualline

C++ Hackers Guide next_ptr = cur_ptrNHlin8 c pre$_ptr; pre$_ptr = cur_ptr; cur_ptr = next_ptr; L

Steve Oualline

% si#ilar syste# can ,e used to go through the list in reverse !here are a )e" casts and a lot o) details o#itted )ro# this code %lso ;5# going to let the reader )igure out to insert and re#ove noted Ho"ever these days, #e#ory is cheap, progra##ers are e&pensive, and it5s )ar #ore cost e))ective to i#ple#ent a dou,le linked list as a dou,le linked list, so this is Kust an acade#ic e&ercise

Hack 13(: 7ccessin* Shared Memor! Witho%t a Lock


The Problem: Ho" do you synchroniFe t"o processes "hich share #e#ory "ithout using a test and set or lock instruction The Hack: !here are several algorith#s to do this ,elo" One o) the# is listed

!his algorith# uses the )ollo"ing code to enter the critical section and access the shared resource* 1 Set a flag indicating that this process is no" atte#pting to enter the critical section 2 Set the tu(n varia,le to indicate that this process "ants in !he tu(n varia,le "ill hold the ;9 o) the last process to atte#pt entry 4 ;) the other process "ants the critical section and "e "ere the last one to access the tu(n varia,le, "ait 0% CP. consu#ing spin "ait is used in this e&a#ple 2 > 9o the critical stu)) ? Set the flag to indicate that "e are no longer in the critical section // Index ,or ,lag and turn $aria#les enu: process K30/.!66_( = ;) 30/.!66_* = (L; // I, true) I': tr%ing to go critical $olatile #ool ,lagT*U = K,alse) ,alseL; // -ho's turn is it now Page 20B Copyright 2008, Steve Oualline

C++ Hackers Guide $olatile int turn = 30/.!66_(; $oid process_(&' K ,lagT30/.!66_(U = true; turn = 30/.!66_(; while &,lagT30/.!66_*U >> &turn == 30/.!66_('' continue; // do nothing do_critical&'; ,lagT30/.!66_(U = ,alse; L $oid process_*&' K ,lagT30/.!66_*U = true; turn = 30/.!66_*; while &,lagT30/.!66_(U >> &turn == 30/.!66_*'' continue; // do nothing do_critical&'; ,lagT30/.!66_*U = ,alse; L

Steve Oualline

%s hackers "e tend to think ,eyond the ,oundaries o) the pro,le# ;n this e&a#ple "e care)ul to use the volatile key"ord to #ake sure that the #e#ory "as actually changed and that the opti#iFer didn5t play ga#es "ith our code @ut hard"are can play tricks on us too $et5s suppose these processes are running on di))erent CP.s ;) the processors have caches, the changes to flag and tu(n could ,e #ade in a local cache only and not copied to the shared #e#ory ;) this is the case "e need to add so#e cache )lush instructions to this syste# !here are other =uestions to ask as "ell, such as "hy "e don5t have a so#e sort o) hard"are locking #echanis#, or at least a test and set instruction !here are a lot o) unans"ered =uestions to think a,out @ut this pro,le# is a good e&ercise "hen it co#es to )iguring out all the )unny things that can happen in #ultiple process progra##ing (ou have to ,e a"are that any process can run at any ti#e and any shared varia,le can change at any ti#e to ,e really e))ective "hen it co#es to this type o) progra##ing

Page 208

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Hack 13+: 7ns"erin* the 80Fect 8riented Challen*e


The Problem: So#e people are )anatical a,out their progra##ing #ethodology and re)use to ackno"ledge that any other syste# #ay ,e ,etter % lot o) people think that o,Kect oriented progra##ing is the only "ay to go and i) every,ody used o,Kect oriented design, all the "orld5s progra##ing pro,le#s "ould ,e solved %s a long ti#e hacker, ;5ve lived through a nu#,er o) )ads, including e&pert progra##ing, arti)icial intelligence, e&tre#e progra##ing, structured design, and #any other %ll o) the# pro#ised to end the "orld5s progra##ing pro,le#s Gone o) the# ever did One o,Kect oriented proponent once issued a challenge /!here is not one progra# that can not ,e #ade ,etter through the use o) o,Kects,3 he said !he challenge, )ind such a progra# The Hack* !he true co##and ;n order to ,e )air, ; choose as an e&a#ple a real progra# that does real use)ul "ork ;t5s actually part o) the $inu& and .G;T standard co##and set !he co##and is true ;t5s Ko, is to return a status o) true to the operating syste# )or use in scripting !he )ollo"ing is a s#all e&a#ple o) shell scripting "hich uses this co##and* i, T true U; then echo It is true ,i Go" here is the C++ "hich ; "rote "ithout using o,Kect oriented design* int :ain&' K return &;'; L ;5# looking )or"ard to seeing ho" the o,Kect oriented guru can #ake this progra# ,etter through the user o) o,Kect Go" so#e people #ight say ;5# stretching the rules a ,it ; a#, ,ut that5s "hat hackers are supposed to do 6e test the li#its o) the "orld "e live in and so#eti#es "e "ind up #aking ne" li#its 6e also don5t lock ourselves into one technology Kust ,ecause so#eone says it5s good ;t has to actually ,e good )or us to use it %s hackers the only thing "e )anatical a,out is good code and "ill use anything to create it Page 207 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!here are so#e other things to note a,out this progra# 'irst the C version o) this code is e&actly the sa#e as the C++ one On .G;T this "as originally i#ple#ented as a shell script containing 0 lines On #y Solaris ,o&, it is a shell script "hich has in it nothing ,ut )ive copyright notices, a "arning telling #e that the contents are unpu,lished prosperity code, and a version nu#,er* 1 A Go co##ands !he version nu#,er is #ost interesting, since the script contains no code 6hat did they get "rong in versions 1 0 through 1 ? that got )i&ed in 1 AS !he version o) the co##and that ships "ith $inu& contains options One prints out the version nu#,er o) the co##and, the other prints out a help te&t that tells you that the only option is the one to print out the version nu#,er ;ncidentally the version nu#,er on #y syste# is ? 2 1 %gain one has to "onder "hat "as "rong "ith the previous versionsS So the true co##and serves t"o purposes One it sho"s ho" a,solute state#ents such as /; can #ake it ,etter "ith o,Kects3 aren5t al"ays true %nd it also sho"s ho" #anagers, copyright la"yers, and other )orces can add needless co#ple&ity to a progra# that the closest thing to a nothing progra# that ; kno" o)

Page 210

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'ppendi5 ': Hacker 6uotes


!he speed o) a nonC"orking progra# is irrelevant CC .nkno"n Pro)anity is the one language all progra##ers kno" ,est CC .nkno"n 9on5t ,elieve the re=uire#ents, #anage#ent, or the users Progra# as i) they they don5t kno" "hat they really "ant .sually they don5t CC Steve Oualline !he purpose o) a schedule is to tell you ho" late you really are CC .nkno"n Oualline5s la" o) docu#entation* 70\ o) the ti#e the docu#entation "ill ,e lost Out o) the re#aining 10\, 7\ o) the ti#e it "ill ,e the "rong version !he one ti#e you have the correct docu#entation and the correct version o) the docu#entation, it "ill ,e "ritten in Chinese O5Shea5s la"* 8urphy "as an opti#ist ;ts not possi,le )or a progra# to #eet re=uire#ents unless the re=uire#ents have actually ,een de)ined CC Steve Oualline ;ts not possi,le to #eet schedule unless you have one CC Steve Oualline 6hy is there never enough ti#e to do it right, ,ut al"ays enough ti#e to do it over CC .nkno"n !he )irst 70\ o) your progra# "ill take 70\ o) your allocated ti#e to create So "ill the last 10\ CC Steve Oualline U!o ,e or not to ,e, CCthat is the =uestion 3 Shakespeare on ,oolean alge,ra Ha#let, %ct ;;;, Scene 1 /@loody ;nstructions, "hich ,eing taught, return to plague the inventor,3 Shakespeare on #aintenance progra##ing 8ac,eth %ct 1, Scene A

Grace Hopper
;nventor o) the )irst co#piler 0CO@O$2 and "ell kno"n )or )inding a #oth ,eaten to death ,y the contacts o) a relay ,ased co#puter 0!his incident has given rise to the legend 0incorrect2 that this "as the )irst co#puter ,ug2 Page 211 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he "onder)ul thing a,out standards is that there are so #any o) the# to choose )ro# U!he #ost da#aging phrase in the language is* 6e5ve al"ays done it this "ay U ;) it5s a good idea, go ahead and do it ;t5s #uch easier to apologiFe than it is to get per#ission

Lin%s )or1alds
%uthor o) $inu&

%ny progra# is only as good as it is use)ul ;5# generally a very prag#atic person* that "hich "orks, "orks ;n #any cases, the user inter)ace to a progra# is the #ost i#portant part )or a co##ercial co#pany* "hether the progra#s "orks correctly or not see#s to ,e secondary $inu& tends to have )e"er rules than other develop#ents, and any,ody can chip in doing "hatever they "ant 8icroso)t isn5t evil, they Kust #ake really crappy operating syste#s !he cy,erspace earnings ; get )ro# $inu& co#e in the )or#at o) having a Get"ork o) people that kno" #e and trust #e, and that ; can depend on in return !he #e#ory #anage#ent on the Po"erPC can ,e used to )righten s#all children See, you not only have to ,e a good coder to create a syste# like $inu&, you have to ,e a sneaky ,astard too ;) you need #ore than 4 levels o) indentation, you5re scre"ed any"ay, and should )i& your progra# (ou kno" you5re ,rilliant, ,ut #ay,e you5d like to understand "hat you did 2 "eeks )ro# no" !alk is cheap Sho" #e the code -eally, ;5# not out to destroy 8icroso)t !hat "ill Kust ,e a co#pletely unintentional side e))ect
Page 212 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

!he )act that %CP; "as designed ,y a group o) #onkeys high on $S9, and is so#e o) the "orst designs in the industry o,viously #akes running it at any point pretty da#n ugly Given enough eye,alls, all ,ugs are shallo" ; "ill, in )act, clai# that the di))erence ,et"een a ,ad progra##er and a good one is "hether he considers his code or his data structures #ore i#portant @ad progra##ers "orry a,out the code Good progra##ers "orry a,out data structures and their relationships

Page 214

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'ppendi5 /: 7ou 8no9 7ou're a Hacker :f;;;


(ou kno" you5re a hacker i) your house has #ore co#puters in it than !Es you kno" at least seven people ,y their eC#ail address, ,ut have )orgotten their na#es you5ve "atched a #ovie o) t"o people #aking love on a co#puter desk and tried to )igure out "hat kind o) co#puter "as in the ,ackground you have #e#oriFed the nu#,er o) at least one piFFa place "hich "ill deliver to the co#puter la, a)ter #idnight, you5ve lived on ra#en noodles )or #ore than a "eek you5ve disasse#,led a progra# to see "hy it ticked you5ve gone up to a co#plete stranger and asked the# "hat sort o) laptop they are using, everyone in your )a#ily co#es to you "ith their co#puter pro,le#s you taken o)) the covers o) all your co#puters at least once you na#ed your daughter a)ter Grace Hopper

Page 21>

Copyright 2008, Steve Oualline

C++ Hackers Guide Grace Oualline 0%ge 42 you5ve ever use the ter# !CP1;P during a date

Steve Oualline

your "i)e has stood naked ne&t to the co#puter and asked you U9o you "ant to "ork on the co#puter or #ake loveSU and you had to think a,out the ans"er you thought a,out the ans"er then decided to )i& Kust one #ore ,ug you5ve edited a progra# on a laptop you ,rought to 9isneyland played co#puter ga#es )or less than an hour ,e)ore trying to disasse#,le the thing to )igure out ho" it "orked once you )igured out ho" the ga#e "orked, decided to i#prove it "ired a household appliance to a co#puter ever said /; no" kno" the di))erence ,et"een ` and ``3 to so#eone "ho understood e&actly "hat you #eant 0` is pronounced /and3 2

Page 21?

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'ppendi5 C: Hacking Sins


Usin* the letters 8> l> I as 1aria0le names
;n case you didn5t notice "e are talking a,out the upper case letter /O3, the upper case letter /;3 and the lo"er case letter 0l2 0$o"er case $2 !he )act that ; have to include the previous sentence in this ,ook should tell you ho" easily it is to #istake these varia,le )or so#ething else 'or e&a#ple, can you tell the di))erence ,et"een the letter 0 and the nu#,er O ;) you can, then you kno" ; got the# ,ack"ards in the previous sentence

=ot Sharin* :o%r Work


% ,ig part o) ,eing a hacker is helping other people ,eco#e hackers, or at least help the# #ake #ore e))ective use o) their co#puters !he GP$ is all a,ort sharing (ou can use the "ork o) others as long as you share your "ork "ith the#

=o Comments
;5ve heard that the ne&t great progra##ing language is going to ,e so easy to "rite in that you "on5t need co##ents .n)ortunately ; heard that 40 years ago and the language in =uestion "as 'O-!-%G ;; !hey also said it a,out CO@O$ !hey "ere "rong :nglish is still one o) the ,est "ays o) co##unicating "ith people Got using it to e&plain "hat you do #eans that you5ve created a cryptic #ess "hich can5t ,e shared ,y other people

IncOnsisTencY
6hen you progra# consistently you create patterns "hich allo" other people to easily understand and aug#ent your code ;nconsistency creates con)usion and disrupts the "ork process 0;nconsistency is ,ook "riting #eans that you have to e&plain to copy editor "hy your strange )or#atting is really Kust an atte#pt to hu#or !hey keep #issing the Koke and trying to )i& it 2

Page 21A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

D%plicatin* Code A'ro*rammin* 0! C%t and 'asteB


!here is a type o) progra##er out there "ho "hen )aced "ith a pro,le#, "ill si#ply use his te&t editor to copy so#e code that does so#ething si#ilar, #ake a )e" changes, and release his solution 7?\ o) his /ne"3 code is copied and ?\ is original "ork 0i) that #uch2 !his type o) progra##er is called a hack 0;n spite o) the si#ilarities in the na#es, /hack3 and /hacker3 are co#plete opposites 2 % hacker #odi)ies the e&isting )unction to #ake it #ore general and #ore use)ul to a large audience Cut and paste progra##ing is one "ay o) creating large progra#s "hich are i#possi,le to #aintain Hackers like s#all, "ell cra)ted, "ell designed code, instead o) =uickly constructed large #esses

Page 21B

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'ppendi5 $: 0pen Source Tools "or Hackers


cta*s P #%nction Inde&in* S!stem
!he original .G;T ctags "as rather li#ited, so :&u,erant Ctags "as created ;t has #any e&tended )eatures ,eyond the ,asic ctags )unctionality 6ritten ,y 9arren Hie,ert it can ,e )ound at http*11ctags source)orge net1

do&!*en
% syste# )or e#,edding docu#entation inside a C or C++ progra# 0as "ell as so#e other languages 2 6hen used on a "hole syste# this is a very e))ective tool )or generating code docu#entation %vaila,le )ro# http*11""" do&ygen org

#la"#inder
%nalyFes code )or potential security pro,le#s %vaila,le )ro# http*11""" d"heeler co#1)la")inder1

*cc P )he G=U C and CKK compiler s%ite


!his is a high =uality "ith lots o) e&tensions "hich #ake progra##ing easier and #ore relia,le ;t "as "ritten ,y hackers )or hackers and it sho"s %vaila,le at http*11""" gnu org

l&r
$inu& cross re)erence %ctually this tool "ill cross re)erence any progra# and produce a set o) hyperClinked )iles "hich #ake it easy to navigate through large progra#s !he progra# can o,tained at* http*11l&r linu& no1

Page 218

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'erl A,or perldoc and related toolsB P Doc%mentation S!stem


Perl contains tools )or #anipulating docu#ents in PO9 0Plain Old 9ocu#entation2 )or#at !his )or#at is the standard "ay o) docu#enting Perl code, ,ut it "orks )or C and C++ as "ell (ou can get perl )ro# http*11""" perl org

1al*rind Amemor! checkin* toolsB


% tool "hich checks )or #e#ory corruption and as "ell as the use o) uninitialiFed #e#ory (ou can do"nload the progra# )ro#* http*11""" valgrind org

;im A;i Impro1edB


% te&t editor Having said that, it does its Ko, very very "ell and contains lots o) )eatures designed to #ake progra##ing easier .nlike integrated develop#ent environ#ents 0;9:s2 "hich try do #ultiple Ko,s, Ei# edits te&t and that5s it !rue it does have inter)aces to co#pilers and other tools, ,ut its #ain Ko, is te&t editing !he learning curve is a little steep )or Ei# ,ut once you learn ho" to use it you can edit )iles =uicker than any other editor 2?

Ei# can ,e do"nloaded )ro# http*11""" vi# org

2? People "ho love the :8%CS editor and others #ay dispute this clai#

Page 217

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'ppendi5 ): Safe $esign Patterns


1E Eliminate side e,,ectE '%t KK and 44 on lines 0! themsel1esE
MMi; NNi; iMM; // "ood // "ood // "ood #ut ine,,icient &6ee JJJ'

a = iMM; // 1ad aTiU = iMM; // V!0G #ad

2E Don6t p%t assi*nment statements inside other statements


// 1ad and pro#a#l% wrong i, &x = F' === // "ood x = F; i, &x R= ;' ===

3E De,inin* Constants
.se const i) possi,le* const int -I7+I = F;; ;) you #ust use &define put the value in 02* Jde,ine A0!A &F; * (;'

(E Use inline ,%nctions instead o, parameteri<ed macros


inline int sYuare&int i' K return &i*i'; L ;) you #ust use para#eteriFed #acros, put parentheses 02 around each argu#ent Jde,ine 6W2A0!&i' &&i' * &i''

Page 220

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

+E Use NO to eliminate am0i*%o%s code


// Ver% #ad i, &a' i, &#' do_alpha&' else do_#eta&'; // "ood and indented too i, &a' K i, &#' K do_alpha&'; L else K do_#eta&'; L L So#e people 0especially Perl progra##ers2 say you should al"ays include the curly ,races

.E -e o01io%s a0o%t e1er!thin* !o% do> e1en nothin* ,or &i = ;; #u,,erTiU R= 'x'; MMi' continue; switch &state' K case (: do_stage_(&'; // 5all throught case *: do_stage_*&'; #rea8; de,ault: // 6hould ne$er happen assert&I:possi#le state == ;'; a#ort&'; L /E 7l"a!s check ,or the de,a%lt case in a s"itch
See a,ove

2E 'recedence R%les
1 8ultiply 0H2 and divide 012 co#e ,e)ore addition 0+2 and su,traction 0C2

Page 221

Copyright 2008, Steve Oualline

C++ Hackers Guide 2 Put parentheses 02 around everything else

Steve Oualline

3E Header #iles
%l"ays include your o"n header )ile /* 5ile: report=c */ === Jinclude report=h Protect against dou,le inclusion* /* 5ile report=h */ Ji,nde, __0!3/0+_I__ Jde,ine __0!3/0+_I__ // ==== Jendi, /* __0!3/0+_I__ */

15E Check User Inp%t


6hen checking user input al"ays check )or "hat5s per#itted, never check )or "hat5s e&cluded !hat "ay i) you #ake a #istake you #ay accidentally prevent the inclusion o) so#e good data, ,ut you don5t let ,ad data through

11E 7rra! 7ccess


assert&&index H= ;' >> &index C &si<eo,&arra%' / si<eo,&arra%T;U'''; $alue = arra%TindexU; // or arra%TindexU = $alue;

12E Cop!in* 7 Strin*


strncp%&dest) source) si<eo,&dest'';

13E Strin* Concatenation


strncat&dest) source) si<eo,&dest' V strlen&dest''; destTsi<eo,&dest'N(U = '@;';

1(E Cop!in* Memor!


:e:cp%&dest) source) si<eo,&dest'';

1+E Ceroin* memor!


:e:set&dest) '@;') si<eo,&dest''; Page 222 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

1.E #indin* the =%m0er o, Elements in an 7rra!


n_ele:ents = si<eo,&arra%' / si<eo,&arra%T;U';

1/E Usin* *ets


9on5t use gets !here is no "ay to #ake it sa)e .se fgets instead

12E Usin* ,*ets


,gets&string) si<eo,&string') in_,ile';

13E When creatin* opa$%e t!pes> make them checka0le 0! the compiler
struct ,ont_handle K int handle; L; struct window_handle K int handle; L struct :e:or%_handle K int handle; L

25E Cero pointers a,ter delete?,ree to a1oid re%se


delete ptr; ptr = N2 ; ,ree&#_ptr'; #_ptr = N2 ;

21E 7l"a!s check ,or sel, assi*nment


class a_class K pu#lic: a_class> operator = &a_class> other' K i, &>other == this' return &other'; L

22E Use snprint, to create strin*


snprint,&#u,,er) si<eo,&#u,,er') ,ile=\d) seYuence'; Page 224 Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

Page 22>

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

'ppendi5 ": Creati+e Commons <icense


License
!H: 6O-< 0%S 9:';G:9 @:$O62 ;S P-OE;9:9 .G9:- !H: !:-8S O' !H;S C-:%!;E: CO88OGS P.@$;C $;C:GS: 0UCCP$U O- U$;C:GS:U2 !H: 6O-< ;S P-O!:C!:9 @( COP(-;GH! %G91O- O!H:- %PP$;C%@$: $%6 %G( .S: O' !H: 6O-< O!H:- !H%G %S %.!HO-;I:9 .G9:- !H;S $;C:GS: O- COP(-;GH! $%6 ;S P-OH;@;!:9 @( :T:-C;S;GG %G( -;GH!S !O !H: 6O-< P-OE;9:9 H:-:, (O. %CC:P! %G9 %G-:: !O @: @O.G9 @( !H: !:-8S O' !H;S $;C:GS: !O !H: :T!:G! !H;S $;C:GS: 8%( @: COGS;9:-:9 !O @: % COG!-%C!, !H: $;C:GSO- G-%G!S (O. !H: -;GH!S COG!%;G:9 H:-: ;G COGS;9:-%!;OG O' (O.- %CC:P!%GC: O' S.CH !:-8S %G9 COG9;!;OGS !6 *efinitions a <Collective Work< #eans a "ork, such as a periodical issue, anthology or encyclopedia, in "hich the 6ork in its entirety in un#odi)ied )or#, along "ith one or #ore other contri,utions, constituting separate and independent "orks in the#selves, are asse#,led into a collective "hole % "ork that constitutes a Collective 6ork "ill not ,e considered a 9erivative 6ork 0as de)ined ,elo"2 )or the purposes o) this $icense , <*erivative Work< #eans a "ork ,ased upon the 6ork or upon the 6ork and other preCe&isting "orks, such as a translation, #usical arrange#ent, dra#atiFation, )ictionaliFation, #otion picture version, sound recording, art reproduction, a,ridg#ent, condensation, or any other )or# in "hich the 6ork #ay ,e recast, trans)or#ed, or adapted, e&cept that a "ork that constitutes a Collective 6ork "ill not ,e considered a 9erivative 6ork )or the purpose o) this $icense 'or the avoidance o) dou,t, "here the 6ork is a #usical co#position or sound recording, the synchroniFation o) the 6ork in ti#edCrelation "ith a #oving i#age 0UsynchingU2 "ill ,e considered a 9erivative 6ork )or the purpose o) this $icense c <Licensor< #eans the individual, individuals, entity or entities that o))ers the 6ork under the ter#s o) this $icense d <=riginal ,uthor< #eans the individual, individuals, entity or entities "ho created the 6ork e <Work< #eans the copyrighta,le "ork o) authorship o))ered under the ter#s o) this $icense Page 22? Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

) <>ou< #eans an individual or entity e&ercising rights under this $icense "ho has not previously violated the ter#s o) this $icense "ith respect to the 6ork, or "ho has received e&press per#ission )ro# the $icensor to e&ercise rights under this $icense despite a previous violation "6 1air ?se -ights6 Gothing in this license is intended to reduce, li#it, or restrict any rights arising )ro# )air use, )irst sale or other li#itations on the e&clusive rights o) the copyright o"ner under copyright la" or other applica,le la"s #6 License )rant6 Su,Kect to the ter#s and conditions o) this $icense, $icensor here,y grants (ou a "orld"ide, royaltyC)ree, nonCe&clusive, perpetual 0)or the duration o) the applica,le copyright2 license to e&ercise the rights in the 6ork as stated ,elo"* a to reproduce the 6ork, to incorporate the 6ork into one or #ore Collective 6orks, and to reproduce the 6ork as incorporated in the Collective 6orks] , to create and reproduce 9erivative 6orks provided that any such 9erivative 6ork, including any translation in any #ediu#, takes reasona,le steps to clearly la,el, de#arcate or other"ise identi)y that changes "ere #ade to the original 6ork 'or e&a#ple, a translation could ,e #arked U!he original "ork "as translated )ro# :nglish to Spanish,U or a #odi)ication could indicate U!he original "ork has ,een #odi)ied U]] c to distri,ute copies or phonorecords o), display pu,licly, per)or# pu,licly, and per)or# pu,licly ,y #eans o) a digital audio trans#ission the 6ork including as incorporated in Collective 6orks] d to distri,ute copies or phonorecords o), display pu,licly, per)or# pu,licly, and per)or# pu,licly ,y #eans o) a digital audio trans#ission 9erivative 6orks e 'or the avoidance o) dou,t, "here the 6ork is a #usical co#position* i Performance -oyalties ?nder +lanket Licenses $icensor "aives the e&clusive right to collect, "hether individually or, in the event that $icensor is a #e#,er o) a per)or#ance rights society 0e g %SC%P, @8;, S:S%C2, via that society, royalties )or the pu,lic per)or#ance or pu,lic digital per)or#ance 0e g "e,cast2 o) the 6ork

Page 22A

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

ii Mechanical -ights and 'tatutory -oyalties $icensor "aives the e&clusive right to collect, "hether individually or via a #usic rights agency or designated agent 0e g Harry 'o& %gency2, royalties )or any phonorecord (ou create )ro# the 6ork 0Ucover versionU2 and distri,ute, su,Kect to the co#pulsory license created ,y 1B .SC Section 11? o) the .S Copyright %ct 0or the e=uivalent in other Kurisdictions2 ) Webcasting -ights and 'tatutory -oyalties 'or the avoidance o) dou,t, "here the 6ork is a sound recording, $icensor "aives the e&clusive right to collect, "hether individually or via a per)or#anceCrights society 0e g Sound:&change2, royalties )or the pu,lic digital per)or#ance 0e g "e,cast2 o) the 6ork, su,Kect to the co#pulsory license created ,y 1B .SC Section 11> o) the .S Copyright %ct 0or the e=uivalent in other Kurisdictions2 !he a,ove rights #ay ,e e&ercised in all #edia and )or#ats "hether no" kno"n or herea)ter devised !he a,ove rights include the right to #ake such #odi)ications as are technically necessary to e&ercise the rights in other #edia and )or#ats %ll rights not e&pressly granted ,y $icensor are here,y reserved $6 -estrictions6 !he license granted in Section 4 a,ove is e&pressly #ade su,Kect to and li#ited ,y the )ollo"ing restrictions* a (ou #ay distri,ute, pu,licly display, pu,licly per)or#, or pu,licly digitally per)or# the 6ork only under the ter#s o) this $icense, and (ou #ust include a copy o), or the .ni)or# -esource ;denti)ier )or, this $icense "ith every copy or phonorecord o) the 6ork (ou distri,ute, pu,licly display, pu,licly per)or#, or pu,licly digitally per)or# (ou #ay not o))er or i#pose any ter#s on the 6ork that restrict the ter#s o) this $icense or the a,ility o) a recipient o) the 6ork to e&ercise the rights granted to that recipient under the ter#s o) the $icense (ou #ay not su,license the 6ork (ou #ust keep intact all notices that re)er to this $icense and to the disclai#er o) "arranties 6hen (ou distri,ute, pu,licly display, pu,licly per)or#, or pu,licly digitally per)or# the 6ork, (ou #ay not i#pose any technological #easures on the 6ork that restrict the a,ility o) a recipient o) the 6ork )ro# (ou to e&ercise the rights granted to that recipient under the ter#s o) the $icense !his Section >0a2 applies to the 6ork as incorporated in a Collective 6ork, ,ut this does not re=uire the Collective 6ork apart )ro# the 6ork itsel) to ,e #ade su,Kect to the ter#s o) this $icense ;) (ou create a Collective 6ork, upon notice )ro# any $icensor (ou #ust, to the e&tent practica,le, re#ove )ro# the Collective 6ork any credit as re=uired ,y Section >0,2, as re=uested ;) (ou create a 9erivative 6ork, upon notice )ro# any $icensor (ou #ust, to the e&tent practica,le, re#ove )ro# the 9erivative 6ork any credit as re=uired ,y Section >0,2, as re=uested Page 22B Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

, ;) (ou distri,ute, pu,licly display, pu,licly per)or#, or pu,licly digitally per)or# the 6ork 0as de)ined in Section 1 a,ove2 or any 9erivative 6orks 0as de)ined in Section 1 a,ove2 or Collective 6orks 0as de)ined in Section 1 a,ove2, (ou #ust, unless a re=uest has ,een #ade pursuant to Section >0a2, keep intact all copyright notices )or the 6ork and provide, reasona,le to the #ediu# or #eans (ou are utiliFing* 0i2 the na#e o) the Original %uthor 0or pseudony#, i) applica,le2 i) supplied, and1or 0ii2 i) the Original %uthor and1or $icensor designate another party or parties 0e g a sponsor institute, pu,lishing entity, Kournal2 )or attri,ution 0U%ttri,ution PartiesU2 in $icensor5s copyright notice, ter#s o) service or ,y other reasona,le #eans, the na#e o) such party or parties] the title o) the 6ork i) supplied] to the e&tent reasona,ly practica,le, the .ni)or# -esource ;denti)ier, i) any, that $icensor speci)ies to ,e associated "ith the 6ork, unless such .-; does not re)er to the copyright notice or licensing in)or#ation )or the 6ork] and, consistent "ith Section 40,2 in the case o) a 9erivative 6ork, a credit identi)ying the use o) the 6ork in the 9erivative 6ork 0e g , U'rench translation o) the 6ork ,y Original %uthor,U or UScreenplay ,ased on original 6ork ,y Original %uthorU2 !he credit re=uired ,y this Section >0,2 #ay ,e i#ple#ented in any reasona,le #anner] provided, ho"ever, that in the case o) a 9erivative 6ork or Collective 6ork, at a #ini#u# such credit "ill appear, i) a credit )or all contri,uting authors o) the 9erivative 6ork or Collective 6ork appears, then as part o) these credits and in a #anner at least as pro#inent as the credits )or the other contri,uting authors 'or the avoidance o) dou,t, (ou #ay only use the credit re=uired ,y this Section )or the purpose o) attri,ution in the #anner set out a,ove and, ,y e&ercising (our rights under this $icense, (ou #ay not i#plicitly or e&plicitly assert or i#ply any connection "ith, sponsorship or endorse#ent ,y the Original %uthor, $icensor and1or %ttri,ution Parties, as appropriate, o) (ou or (our use o) the 6ork, "ithout the separate, e&press prior "ritten per#ission o) the Original %uthor, $icensor and1or %ttri,ution Parties %6 -epresentations@ Warranties and *isclaimer

Page 228

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

.G$:SS O!H:-6;S: 8.!.%$$( %G-::9 !O @( !H: P%-!;:S ;G 6-;!;GG, $;C:GSO- O'':-S !H: 6O-< %SC;S %G9 OG$( !O !H: :T!:G! O' %G( -;GH!S H:$9 ;G !H: $;C:GS:9 6O-< @( !H: $;C:GSO- !H: $;C:GSO- 8%<:S GO -:P-:S:G!%!;OGS O- 6%--%G!;:S O' %G( <;G9 COGC:-G;GG !H: 6O-<, :TP-:SS, ;8P$;:9, S!%!.!O-( O- O!H:-6;S:, ;GC$.9;GG, 6;!HO.! $;8;!%!;OG, 6%--%G!;:S O' !;!$:, 8%-<:!%@;$;!(, 8:-CH%G!;@;$;!(, ';!G:SS 'O- % P%-!;C.$%- P.-POS:, GOG;G'-;GG:8:G!, O- !H: %@S:GC: O' $%!:G! O- O!H:- 9:':C!S, %CC.-%C(, O- !H: P-:S:GC: O' %@S:GC: O' :--O-S, 6H:!H:- OGO! 9;SCOE:-%@$: SO8: Y.-;S9;C!;OGS 9O GO! %$$O6 !H: :TC$.S;OG O' ;8P$;:9 6%--%G!;:S, SO S.CH :TC$.S;OG 8%( GO! %PP$( !O (O. A6 Limitation on Liability6 :TC:P! !O !H: :T!:G! -:L.;-:9 @( %PP$;C%@$: $%6, ;G GO :E:G! 6;$$ $;C:GSO- @: $;%@$: !O (O. OG %G( $:G%$ !H:O-( 'O- %G( SP:C;%$, ;GC;9:G!%$, COGS:L.:G!;%$, P.G;!;E: O- :T:8P$%-( 9%8%G:S %-;S;GG O.! O' !H;S $;C:GS: O!H: .S: O' !H: 6O-<, :E:G ;' $;C:GSO- H%S @::G %9E;S:9 O' !H: POSS;@;$;!( O' S.CH 9%8%G:S B6 Termination a !his $icense and the rights granted hereunder "ill ter#inate auto#atically upon any ,reach ,y (ou o) the ter#s o) this $icense ;ndividuals or entities "ho have received 9erivative 6orks 0as de)ined in Section 1 a,ove2 or Collective 6orks 0as de)ined in Section 1 a,ove2 )ro# (ou under this $icense, ho"ever, "ill not have their licenses ter#inated provided such individuals or entities re#ain in )ull co#pliance "ith those licenses Sections 1, 2, ?, A, B, and 8 "ill survive any ter#ination o) this $icense , Su,Kect to the a,ove ter#s and conditions, the license granted here is perpetual 0)or the duration o) the applica,le copyright in the 6ork2 Got"ithstanding the a,ove, $icensor reserves the right to release the 6ork under di))erent license ter#s or to stop distri,uting the 6ork at any ti#e] provided, ho"ever that any such election "ill not serve to "ithdra" this $icense 0or any other license that has ,een, or is re=uired to ,e, granted under the ter#s o) this $icense2, and this $icense "ill continue in )ull )orce and e))ect unless ter#inated as stated a,ove C6 Miscellaneous

Page 227

Copyright 2008, Steve Oualline

C++ Hackers Guide

Steve Oualline

a :ach ti#e (ou distri,ute or pu,licly digitally per)or# the 6ork 0as de)ined in Section 1 a,ove2 or a Collective 6ork 0as de)ined in Section 1 a,ove2, the $icensor o))ers to the recipient a license to the 6ork on the sa#e ter#s and conditions as the license granted to (ou under this $icense , :ach ti#e (ou distri,ute or pu,licly digitally per)or# a 9erivative 6ork, $icensor o))ers to the recipient a license to the original 6ork on the sa#e ter#s and conditions as the license granted to (ou under this $icense c ;) any provision o) this $icense is invalid or unen)orcea,le under applica,le la", it shall not a))ect the validity or en)orcea,ility o) the re#ainder o) the ter#s o) this $icense, and "ithout )urther action ,y the parties to this agree#ent, such provision shall ,e re)or#ed to the #ini#u# e&tent necessary to #ake such provision valid and en)orcea,le d Go ter# or provision o) this $icense shall ,e dee#ed "aived and no ,reach consented to unless such "aiver or consent shall ,e in "riting and signed ,y the party to ,e charged "ith such "aiver or consent e !his $icense constitutes the entire agree#ent ,et"een the parties "ith respect to the 6ork licensed here !here are no understandings, agree#ents or representations "ith respect to the 6ork not speci)ied here $icensor shall not ,e ,ound ,y any additional provisions that #ay appear in any co##unication )ro# (ou !his $icense #ay not ,e #odi)ied "ithout the #utual "ritten agree#ent o) the $icensor and (ou

Creati+e Commons *otice


Creative Co##ons is not a party to this $icense, and #akes no "arranty "hatsoever in connection "ith the 6ork Creative Co##ons "ill not ,e lia,le to (ou or any party on any legal theory )or any da#ages "hatsoever, including "ithout li#itation any general, special, incidental or conse=uential da#ages arising in connection to this license Got"ithstanding the )oregoing t"o 022 sentences, i) Creative Co##ons has e&pressly identi)ied itsel) as the $icensor hereunder, it shall have all rights and o,ligations o) $icensor :&cept )or the li#ited purpose o) indicating to the pu,lic that the 6ork is licensed under the CCP$, Creative Co##ons does not authoriFe the use ,y either party o) the trade#ark UCreative Co##onsU or any related trade#ark or logo o) Creative Co##ons "ithout the prior "ritten consent o) Creative Co##ons %ny per#itted use "ill ,e in co#pliance "ith Creative Co##ons5 thenCcurrent trade#ark usage guidelines, as #ay ,e pu,lished on its "e,site or other"ise #ade availa,le upon re=uest )ro# ti#e to ti#e 'or the avoidance o) dou,t, Page 240 Copyright 2008, Steve Oualline

C++ Hackers Guide this trade#ark restriction does not )or# part o) the $icense

Steve Oualline

Creative Co##ons #ay ,e contacted at http*11creativeco##ons org1

Page 241

Copyright 2008, Steve Oualline