Ifdef Considered Harmful, Or Portability Experience with C News

Ifdef Considered Harmful, Or Portability Experience with C News

#ifdef ConsideredHarmful, or Portability ExperienceWith C News HenrySpencer -_Zo9l9gy-Computer Systems, University of Toronto GeoffCollyer - SoftwareTool & Die ABSTRACT We believethat a C programmer'simpulse to use#ifdef in an attemptat portability is usuallya mistake. Portabilityis generallythe resultof advanceplanning rathei than trench warfare.involving #ifdef. In the courseof developingC NewJ on difterent systems,we evolved various tactics. for dealing with differencèsãmong systemswithout producing a welter of #ifdefs at points of difference.We discussthe-altêmadves to, and occasio-nal properuse of, #ifdef. Introduction portability problems are repeatedlyworked around With uNrx running on many different comput- ratherthan solved. The resultis a tangledand often impenetrable ers,vaguely t¡tlD(-like systems running on still more, web. Here's-a noteworthyexample popular and C runningon practicallyeverything, man! peo: from a newsreader.lSee Figure i. Observe that, not content ple are suddenlyfinding it necessaryto pott C with merely nestingfifdefs, the authorhas #ifdef softwarefrom one machineto another. When differ- andordinary if statementsþlus the mysterious encesamong systemscause trouble, the usual first IF macros) interweaving. This makes the structure impulse is to write two different versions of the almost impossible to follow without goingover it code-+ne per system-and use#ifdef to choosethe repeatedly,one case at a time. appropriateone. This is usuallya mistake. Fufhermore,given worst caseelaboration and (each Simple use of #ifdef works acceptablywell nesting fifdef alwayshas a matching#else), when differencesare localizedand only two versions the number of alternativecode paths doub-ieswiitr each extra are present. Unfortunately,as software using this level of #ifdef. By the time the depth reaches (not approachis ported to more and more systems,the 5 at all rare in the work of #ifdef enthusiasts), #ifdefs proliferate, nest, and interlock. After a there are potentially32 alternatecode paths while, the result is usuallyan unreadable,unmain- to consider.How many of thosepaths have tainable mess. Portability without tears requires been tested? Probablytwo or three. How many of betteradvance planning. the possiblecombinations even make sense?Often not very many. Figure2 is anotherwonderful exam- When we wrote C News [Coll87a], we put a ple, the LeaningTower Of Hostnames.It's most high priority on portability, sincewe ran severaldif- unlikely that anyoneunderstands this codeany more. ferent systems ourselves, and expected that the In suchsituations, maintenance is reducedto hit-or- softwarewould eventuallybe usedon many more. miss patching. If you find and fix a bug, how many Planningfor future adaptationssaved us (and others) otherbranches does it needto be fixed on? If vou from trying to force changesinto an uncooperative discover a performancebottleneck and work out a structurewhen we later encounterednew svstems. way to fix it, will you have to apply the fix Porting C News generallyinvolves writing a few separatelyto eachbranch? Now envisionwhat hap- small primitives. Therehave been surprises, but in pens when hurried or carelessmaintainers do¿,, the courseof maintainingand improving the code apply their fixes in all the placeswhere they are and its portability, we insistedthat the software relevant. remain readableand fixable. And we were not preparedto sacrifice performance,since one of C PhilosophicalAspects News's major virtues is that it is far fasterthan older The key step news software. We evolved several tactics that in avoidingsuch messesis to shouldbe widely applicable. realize that portability requiresplanning. There is an abundanceof bad examplesto showthat portabil- The Nature of the Problem ity,cannot be addedonto or patchedinto. unportable software. Many of the problemswe diÉcuis stem Considerwhat happenswhen #ifdef is used from the "never mind good,we want it nextweek" carelessly.T\e first #ifdef probablydoesn't cause much trouble. Unfortunately,they breed. Worse, /To they nest, and tend to becomemore deeplynested quote from the old tx¡x kernel: ..you are not with time. #ifdefs pile on top of *ifdets as expectedto understandthis", '92 Summer USENIX- June8-June l:Z,1rgg? - San Antonio, TX 18s fifdef ConsideredHarmful ... Spencer,&Collyer approachto software. earlier"solution" was really a quick fix and needs Even the best planning canriot anticipate all generalizing. In such cases,it is important to go problems,but it is importantto retain the emphasis back andfix the kludges, The time is not wasted;it on planningeven into ongoingmaintenance. When is an investmentin the future. a new portabilityproblem surfaces, it is importantto More generally, portability requires time and step back and think about the problem and its solu- thought. Nobodygets everythingright the frrst time; tion. Is this a uniqueproblem, or the harbingerof a gettingthe coderight meanstaking the time to think whole new class of them? Usuallv it's the latter. about what went wrong, decide what the mistakes which makesplanning all the more õrucial: how can were, andgo back andfrx them. the solution deal with all of them, not just the The alert readermay notice that almost all the current one? Failure to think leads to the patch- remarksin this sectioncould also be applied to upon-patchapproach to portability,rapidly producing achieving high performance,high reliability, etc., unreadableand unmaintainable code. and that no specificboundary between 'We'vedevelopment Once the problem (class) and the solution are and maintenancewas mentioned. really dis- understood,then and only then it is time to start cussedhow to achievehigh-quality software. In our work on the code. Typically this will mean re- experience,this approachworks; we can't imagine implementingparts of it, not just hackingup the old anyother that would. code to work somehow. This highlights another issue: to revisethe code,you must understandit... Portable Interfaces and that means not making an incomprehensible Systems do, unfortunately,differ. It's often mess this time to interfere with maintenancenext possible to avoid system-dependentareas well time. enoughthat the samecode will run on all systems; All of this is typically more work than just we'll discussthat later. But sometimesmultiple hacking in a quick fix. Sometimesa quick fix may variantsare inevitable. Even within the uNIx family, be necessary,or later thought may show that an there are significant variations between systems. wld lr,ld.! DEllocug cl.¡nu9_!cl ) !aâak_bogua¡ ., { l¡_ch¡a('D.l.t. bolu. ¡d.grouÞ¡? I¡y¡ ,D')¡ ragl.t.E tc_nut .¡. trgtt ..crt.!( bul, ) t !.gt.t.t re_f,Uü bgþ.Lty - 0 t tltC.! vrRr¡l tl,!d.! vln¡O8l Drl¡rqd( ) t ¡l( v.rËor.) ,6d1! , \B't llu88' !Þuta('Chackl¡g out !rou! ,ù&r!c--h69 oû À raco¡d,,,\D.,.!dout) ¡rurch.r( .. 'h') llSSHl 1! lrb{! { E8E llfC.l V!R¡O88 todl! It(v.rbo..l '\ ,L!d.! îER6E lDuÈ. ( Îyt. y b d.ta¡. bogu. nNrl!ouÞ..\n\ lDuÈr l'Ch.ckl,Dg .nfr.rc--hùg on... \n., rÈdouÈ) rLUOHr t6dl! 1y¡1. n ot 8t þ l.Âva th4 rÈ !h. 6d 1r CAr. thry r.Èuh.\n\ ',.tdour) . ¡tg8¡l¡ tor ¡ng* 0, ô9a < nqÈlcl¡¡.t nga++l { il (tor.âdfng¡t >. lR_w8uB) ( tlSl . ,6d1! aat_Þ!a¡d(n9x)t /r thl' ey raaaÈ ndrglouÞ r/ ,ild.t î!R8! /. or d.clâra lt bogua'/ , l9ut.l'y b d.l.È., n !o k..¡,\n.,rèdour) llugHt 1! (Èo!.Àdfn9r¡ .. ÎR-EOCU8) 16di! ÞtoaltY++t goto !a.ak_bcgu.t ) ) - .¡.. ll (.bu!.. ,n' 'buf.. ,q') lot ¡ngr ¡qucll¡.-lr ngx >¡ o ¡¡ ro!.¡dfngnl .. tR_rocust n9¡--) II bo9o.lty--, /. dfacounÈ alla¡dy evad ona¡ i/ .1.. l'! .- 'Y'l l!. (s.rtscll¡. > 5 ¡t bogo.lty > n.xrlclln. / 2) { l'bu! { It¡uE.l Yàll.'(Èa.¡dftr.xÈlclla.-¡l .¡ Aî_loco8 ¡¡ ¡.rlsclln. > O) 'It gha --nrtacll¡at r/ læka llk. actlva !11a la r.a.d upt 6nt¡ct Dasa adñtDlaÈs¡Èor,\D\ /r a.¡1 tough, huh? r..Èdout) !,our t ) !¡ruÈa ( .1.. { 'I.Âva lDut.(hforh.lD,.ÈCouÈ) th. \'bogu¡\. gþuD¡ aloÞ., ¡Dd th.y My c6. back b noml. ¡t¡yb.,\¡\ !!U6H, ',.tdoue) llU8H, r.sll._ddír( ), ) ggco aaaak_boqua, ll!d.! ¡lDocÀtr l t6dl! .1.. lt (bogorlÊy) { ,I!d.l vlRAO88 ) ,.1r. ll(v.rbo¡. ) tltd.! WRAOSI !Þuta(,Eovl¡g bogua Dd.gÞuDa b tha and o! your ,eÍarc.\n,, rtCout) turs[r ¡l I v.!hoa.) t!81 !Þutrl'lou ahould adlt bogua ndagrouDa ouË o! !þur .¡ú¡rc.\D., a6d1! lÈdcuÈ) tlu88, ,l!d.! ÎlRgl ttSE t6dll !Þur.('lbvl¡g bogu... b t¡r. .nd.\tri,¡rdour) !!u8ll, t6dtl tf!d.! îlR8E !9uÊ. bogur.. to! (t ¡gil >. 0, ngr--) { l'ldlr lson,nd.!c.\tr., rtdouc) rr,ug¡t, t6dl! tl lÞr.rdfng¡l .. Zn-Eocus) ,6d1,! ralæata_ndaglou¡r(n9¡rrsÈrctl¡a-1 ) t I ¡f,amold . lESlt Figure 1: Exampleof overuseof #ifdef '92 186 Summer USENIX - June 8-June 12, Lgg2- San Antonio, TX Spencer,& Collyer fifdef ConsideredHarmful ... #lfdef, or somethingsimilar, ultimately is unavoid- makesthe code simpler, cleaner,and more manage- able. It can be managed,however, to minimize able evenwhen no rewriteis expected. problems. As a small casein point, when part of C News Among the basic principles of good software wishes to anange that a file descriptorassociated engineeringare cleaninterfaces and informationhid- with a sldio streambe closedat exectime, to avoid ing: when faced with a decisionthat might change, passingit to unpreparedchildren, this is doneby hide it in one module, with a simple outside-world fclsexec(fp); interface defined independentlyof exactly how the decisionis madeinside. One would think that well- (whereþ is the sfdio structurepointer) rather than educatedmodern programmers would not needto be by some _complexinvocation of. ioctl or something taught the virtues of this technique.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    13 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us