ProgramPortabilityStrongTypeChecking Lint,aCProgramChecker S.C.Johnson ABSTRACT LintisacommandwhichexaminesCsourceprograms,detectinganumber ofbugsandobscurities.ItenforcesthetyperulesofCmorestrictlythantheC compilers.Itmayalsobeusedtoenforceanumberofportabilityrestrictions involvedinmovingprogramsbetweendifferentmachinesand/oroperatingsystems.Anotheroptiondetectsanumberofwasteful,orerrorprone,constructions whichneverthelessare,strictlyspeaking,legal. Lintacceptsmultipleinputfilesandlibraryspecifications,andchecksthem forconsistency. TheseparationoffunctionbetweenlintandtheCcompilershasbothhistoricalandpracticalrationale.ThecompilersturnCprogramsintoexecutable filesrapidlyandefficiently.Thisispossibleinpartbecausethecompilersdonot dosophisticatedtypechecking,especiallybetweenseparatelycompiledprograms. Linttakesamoreglobal,leisurelyviewoftheprogram,lookingmuchmorecarefullyatthecompatibilities. Thisdocumentdiscussestheuseoflint,givesanoverviewoftheimplementation,andgivessomehintsonthewritingofmachineindependentCcode. July26,1978 Lint,aCProgramChecker S.C.Johnson IntroductionandUsage SupposetherearetwoC1sourcefiles,file1.candfile2.c,whichareordinarilycompiledand loadedtogether.Thenthecommand lintfile1.cfile2.c producesmessagesdescribinginconsistenciesandinefficienciesintheprograms.Theprogram enforcesthetypingrulesofCmorestrictlythantheCcompilers(forbothhistoricalandpractical reasons)enforcethem.Thecommand lint−pfile1.cfile2.c willproduce,inadditiontotheabovemessages,additionalmessageswhichrelatetotheportabilityoftheprogramstootheroperatingsystemsandmachines.Replacingthe−pby−hwillproducemessagesaboutvariouserror-proneorwastefulconstructionswhich,strictlyspeaking,are notbugs.Saying−hpgetsthewholeworks. Thenextseveralsectionsdescribethemajormessages;thedocumentcloseswithsections discussingtheimplementationandgivingsuggestionsforwritingportableC.Anappendixgivesa summaryofthelintoptions. AWordAboutPhilosophy Manyofthefactswhichlintneedsmaybeimpossibletodiscover.Forexample,whethera givenfunctioninaprogramevergetscalledmaydependontheinputdata.Decidingwhether exitisevercalledisequivalenttosolvingthefamous‘‘haltingproblem,’’knowntoberecursively undecidable. Thus,mostofthelintalgorithmsareacompromise.Ifafunctionisnevermentioned,itcan neverbecalled.Ifafunctionismentioned,lintassumesitcanbecalled;thisisnotnecessarilyso, butinpracticeisquitereasonable. Linttriestogiveinformationwithahighdegreeofrelevance.Messagesoftheform‘‘xxx mightbeabug’’areeasytogenerate,butareacceptableonlyinproportiontothefractionofreal bugstheyuncover.Ifthisfractionofrealbugsistoosmall,themessageslosetheircredibilityand servemerelytoclutteruptheoutput,obscuringthemoreimportantmessages. Keepingtheseissuesinmind,wenowconsiderinmoredetailtheclassesofmessageswhich lintproduces. UnusedVariablesandFunctions Assetsofprogramsevolveanddevelop,previouslyusedvariablesandargumentstofunctionsmaybecomeunused;itisnotuncommonforexternalvariables,orevenentirefunctions,to becomeunnecessary,andyetnotberemovedfromthesource.These‘‘errorsofcommission’’ rarelycauseworkingprogramstofail,buttheyareasourceofinefficiency,andmakeprograms hardertounderstandandchange.Moreover,informationaboutsuchunusedvariablesandfunctionscanoccasionallyservetodiscoverbugs;ifafunctiondoesanecessaryjob,andisnever called,somethingiswrong! 1 -2-Lintcomplainsaboutvariablesandfunctionswhicharedefinedbutnototherwisemen-tioned.Anexceptionisvariableswhicharedeclaredthroughexplicitexternstatementsbutare neverreferenced;thusthestatement externfloatsin(); willevokenocommentifsinisneverused.NotethatthisagreeswiththesemanticsoftheC compiler.Insomecases,theseunusedexternaldeclarationsmightbeofsomeinterest;theycan bediscoveredbyaddingthe−xflagtothelintinvocation. Certainstylesofprogrammingrequiremanyfunctionstobewrittenwithsimilarinterfaces; frequently,someoftheargumentsmaybeunusedinmanyofthecalls.The−voptionisavailable tosuppresstheprintingofcomplaintsaboutunusedarguments.When−visineffect,nomessagesareproducedaboutunusedargumentsexceptforthoseargumentswhichareunusedand alsodeclaredasregisterarguments;thiscanbeconsideredanactive(andpreventable)wasteof theregisterresourcesofthemachine. Thereisonecasewhereinformationaboutunused,orundefined,variablesismoredistractingthanhelpful.Thisiswhenlintisappliedtosome,butnotall,filesoutofacollectionwhich aretobeloadedtogether.Inthiscase,manyofthefunctionsandvariablesdefinedmaynotbe used,and,conversely,manyfunctionsandvariablesdefinedelsewheremaybeused.The−uflag maybeusedtosuppressthespuriousmessageswhichmightotherwiseappear. Set/UsedInformation Lintattemptstodetectcaseswhereavariableisusedbeforeitisset.Thisisverydifficult todowell;manyalgorithmstakeagooddealoftimeandspace,andstillproducemessagesabout perfectlyvalidprograms.Lintdetectslocalvariables(automaticandregisterstorageclasses) whosefirstuseappearsphysicallyearlierintheinputfilethanthefirstassignmenttothevariable. Itassumesthattakingtheaddressofavariableconstitutesa‘‘use,’’sincetheactualusemay occuratanylatertime,inadatadependentfashion. Therestrictiontothephysicalappearanceofvariablesinthefilemakesthealgorithmvery simpleandquicktoimplement,sincethetrueflowofcontrolneednotbediscovered.Itdoes meanthatlintcancomplainaboutsomeprogramswhicharelegal,buttheseprogramswould probablybeconsideredbadonstylisticgrounds(e.g.mightcontainatleasttwogoto’s).Because staticandexternalvariablesareinitializedto0,nomeaningfulinformationcanbediscovered abouttheiruses.Thealgorithmdealscorrectly,however,withinitializedautomaticvariables,and variableswhichareusedintheexpressionwhichfirstsetsthem. Theset/usedinformationalsopermitsrecognitionofthoselocalvariableswhicharesetand neverused;theseformafrequentsourceofinefficiencies,andmayalsobesymptomaticofbugs. FlowofControl Lintattemptstodetectunreachableportionsoftheprogramswhichitprocesses.Itwill complainaboutunlabeledstatementsimmediatelyfollowinggoto,break,continue,orreturn statements.Anattemptismadetodetectloopswhichcanneverbeleftatthebottom,detecting thespecialcaseswhile(1)andfor(;;)asinfiniteloops.Lintalsocomplainsaboutloopswhich cannotbeenteredatthetop;somevalidprogramsmayhavesuchloops,butatbesttheyarebad style,atworstbugs. Linthasanimportantareaofblindnessintheflowofcontrolalgorithm:ithasnowayof detectingfunctionswhicharecalledandneverreturn.Thus,acalltoexitmaycauseunreachable codewhichlintdoesnotdetect;themostseriouseffectsofthisareinthedeterminationof returnedfunctionvalues(seethenextsection). Oneformofunreachablestatementisnotusuallycomplainedaboutbylint;abreakstatementthatcannotbereachedcausesnomessage.Programsgeneratedbyyacc,2andespecially 2 -3-lex,3mayhaveliterallyhundredsofunreachablebreakstatements.The−OflagintheCcom-pilerwillofteneliminatetheresultingobjectcodeinefficiency.Thus,theseunreachedstatements areoflittleimportance,thereistypicallynothingtheusercandoaboutthem,andtheresulting messageswouldclutterupthelintoutput.Ifthesemessagesaredesired,lintcanbeinvokedwith the−boption. FunctionValues Sometimesfunctionsreturnvalueswhichareneverused;sometimesprogramsincorrectlyuse function‘‘values’’whichhaveneverbeenreturned.Lintaddressesthisprobleminanumberof ways. Locally,withinafunctiondefinition,theappearanceofboth return(expr); and return; statementsiscauseforalarm;lintwillgivethemessage functionnamecontainsreturn(e)andreturn Themostseriousdifficultywiththisisdetectingwhenafunctionreturnisimpliedbyflowofcontrolreachingtheendofthefunction.Thiscanbeseenwithasimpleexample: f(a){ if(a)return(3); g(); } Noticethat,ifatestsfalse,fwillcallgandthenreturnwithnodefinedreturnvalue;thiswill triggeracomplaintfromlint.Ifg,likeexit,neverreturns,themessagewillstillbeproducedwhen infactnothingiswrong. Inpractice,somepotentiallyseriousbugshavebeendiscoveredbythisfeature;italso accountsforasubstantialfractionofthe‘‘noise’’messagesproducedbylint. Onaglobalscale,lintdetectscaseswhereafunctionreturnsavalue,butthisvalueissometimes,oralways,unused.Whenthevalueisalwaysunused,itmayconstituteaninefficiencyin thefunctiondefinition.Whenthevalueissometimesunused,itmayrepresentbadstyle(e.g.,not testingforerrorconditions). Thedualproblem,usingafunctionvaluewhenthefunctiondoesnotreturnone,isalso detected.Thisisaseriousproblem.Amazingly,thisbughasbeenobservedonacoupleofoccasionsin‘‘working’’programs;thedesiredfunctionvaluejusthappenedtohavebeencomputedin thefunctionreturnregister! TypeChecking LintenforcesthetypecheckingrulesofCmorestrictlythanthecompilersdo.Theadditionalcheckingisinfourmajorareas:acrosscertainbinaryoperatorsandimpliedassignments,at thestructureselectionoperators,betweenthedefinitionandusesoffunctions,andintheuseof enumerations. Thereareanumberofoperatorswhichhaveanimpliedbalancingbetweentypesofthe operands.Theassignment,conditional(?:),andrelationaloperatorshavethisproperty;the argumentofareturnstatement,andexpressionsusedininitializationalsosuffersimilarconversions.Intheseoperations,char,short,int,long,unsigned,float,anddoubletypesmaybe freelyintermixed.Thetypesofpointersmustagreeexactly,exceptthatarraysofx’scan,of course,beintermixedwithpointerstox’s. 3 -4-Thetypecheckingrulesalsorequirethat,instructurereferences,theleftoperandofthe—> beapointertostructure,theleftoperandofthe.beastructure,andtherightoperandofthese operatorsbeamemberofthestructureimpliedbytheleftoperand.Similarcheckingisdonefor referencestounions. Strictrulesapplytofunctionargumentandreturnvaluematching.Thetypesfloatand doublemaybefreelymatched,asmaythetypeschar,short,int,andunsigned.Also,pointers canbematchedwiththeassociatedarrays.Asidefromthis,allactualargumentsmustagreein typewiththeirdeclaredcounterparts. Withenumerations,checksaremadethatenumerationvariablesormembersarenotmixed withothertypes,orotherenumerations,andthattheonlyoperationsappliedare=,initialization, ==,!=,andfunctionargumentsandreturnvalues. TypeCasts ThetypecastfeatureinCwasintroducedlargelyasanaidtoproducingmoreportableprograms.Considertheassignment p=1; wherepisacharacterpointer.Lintwillquiterightlycomplain.Now,considertheassignment p=(char∗)1; inwhichacasthasbeenusedtoconverttheintegertoacharacterpointer.Theprogrammer obviouslyhadastrongmotivationfordoingthis,andhasclearlysignaledhisintentions.Itseems harshforlinttocontinuetocomplainaboutthis.Ontheotherhand,ifthiscodeismovedto anothermachine,suchcodeshouldbelookedatcarefully.The−cflagcontrolstheprintingof commentsaboutcasts.When−cisineffect,castsaretreatedasthoughtheywereassignments subjecttocomplaint;otherwise,alllegalcastsarepassedwithoutcomment,nomatterhow strangethetypemixingseemstobe. NonportableCharacterUse OnthePDP-11,charactersaresignedquantities,witharangefrom−128to127.Onmost oftheotherCimplementations,characterstakeononlypositivevalues.Thus,lintwillflagcertaincomparisonsandassignmentsasbeingillegalornonportable.Forexample,thefragment charc; ... if((c=getchar())<0).... worksonthePDP-11,butwillfailonmachineswherecharactersalwaystakeonpositivevalues. Therealsolutionistodeclarecaninteger,sincegetcharisactuallyreturningintegervalues.In anycase,lintwillsay‘‘nonportablecharactercomparison’’. Asimilarissueariseswithbitfields;whenassignmentsofconstantvaluesaremadetobitfields,thefieldmaybetoosmalltoholdthevalue.Thisisespeciallytruebecauseonsome machinesbitfieldsareconsideredassignedquantities.Whileitmayseemunintuitivetoconsider thatatwobitfielddeclaredoftypeintcannotholdthevalue3,theproblemdisappearsifthebitfieldisdeclaredtohavetypeunsigned. Assignmentsoflongstoints Bugsmayarisefromtheassignmentoflongtoanint,whichlosesaccuracy.Thismayhappeninprogramswhichhavebeenincompletelyconvertedtousetypedefs.Whenatypedefvariableischangedfrominttolong,theprogramcanstopworkingbecausesomeintermediate resultsmaybeassignedtoints,losingaccuracy.Sincethereareanumberoflegitimatereasons forassigninglongstoints,thedetectionoftheseassignmentsisenabledbythe−aflag.

-5-StrangeConstructions Severalperfectlylegal,butsomewhatstrange,constructionsareflaggedbylint;themessages hopefullyencouragebettercodequality,clearerstyle,andmayevenpointoutbugs.The−hflag isusedtoenablethesechecks.Forexample,inthestatement ∗p++; the∗doesnothing;thisprovokesthemessage‘‘nulleffect’’fromlint.Theprogramfragment unsignedx; if(x<0)... isclearlysomewhatstrange;thetestwillneversucceed.Similarly,thetest if(x>0)... isequivalentto if(x!=0) whichmaynotbetheintendedaction.Lintwillsay‘‘degenerateunsignedcomparison’’inthese cases.Ifonesays if(1!=0).... lintwillreport‘‘constantinconditionalcontext’’,sincethecomparisonof1with0givesaconstantresult. Anotherconstructiondetectedbylintinvolvesoperatorprecedence.Bugswhicharisefrom misunderstandingsabouttheprecedenceofoperatorscanbeaccentuatedbyspacingandformatting,makingsuchbugsextremelyhardtofind.Forexample,thestatements if(x&077==0)... or x<<2+40 probablydonotdowhatwasintended.Thebestsolutionistoparenthesizesuchexpressions,and lintencouragesthisbyanappropriatemessage. Finally,whenthe−hflagisinforcelintcomplainsaboutvariableswhichareredeclaredin innerblocksinawaythatconflictswiththeiruseinouterblocks.Thisislegal,butisconsidered bymany(includingtheauthor)tobebadstyle,usuallyunnecessary,andfrequentlyabug. AncientHistory Thereareseveralformsofoldersyntaxwhicharebeingofficiallydiscouraged.Thesefall intotwoclasses,assignmentoperatorsandinitialization. Theolderformsofassignmentoperators(e.g.,=+,=−,...)couldcauseambiguousexpressions,suchas a=−1; whichcouldbetakenaseither a=−1; or a=−1; Thesituationisespeciallyperplexingifthiskindofambiguityarisesastheresultofamacrosubstitution.Thenewer,andpreferredoperators(+=,−=,etc.)havenosuchambiguities.Tospur theabandonmentoftheolderforms,lintcomplainsabouttheseoldfashionedoperators.

-6-Asimilarissueariseswithinitialization.Theolderlanguageallowed intx1; toinitializexto1.Thisalsocausedsyntacticdifficulties:forexample, intx(−1); lookssomewhatlikethebeginningofafunctiondeclaration: intx(y){... andthecompilermustreadafairwayspastxinordertosurewhatthedeclarationreallyis.. Again,theproblemisevenmoreperplexingwhentheinitializerinvolvesamacro.Thecurrent syntaxplacesanequalssignbetweenthevariableandtheinitializer: intx=−1; Thisisfreeofanypossiblesyntacticambiguity. PointerAlignment Certainpointerassignmentsmaybereasonableonsomemachines,andillegalonothers,due entirelytoalignmentrestrictions.Forexample,onthePDP-11,itisreasonabletoassigninteger pointerstodoublepointers,sincedoubleprecisionvaluesmaybeginonanyintegerboundary.On theHoneywell6000,doubleprecisionvaluesmustbeginonevenwordboundaries;thus,notall suchassignmentsmakesense.Linttriestodetectcaseswherepointersareassignedtoother pointers,andsuchalignmentproblemsmightarise.Themessage‘‘possiblepointeralignment problem’’resultsfromthissituationwhenevereitherthe−por−hflagsareineffect. MultipleUsesandSideEffects Incomplicatedexpressions,thebestorderinwhichtoevaluatesubexpressionsmaybe highlymachinedependent.Forexample,onmachines(likethePDP-11)inwhichthestackruns backwards,functionargumentswillprobablybebestevaluatedfromright-to-left;onmachines withastackrunningforward,left-to-rightseemsmostattractive.Functioncallsembeddedas argumentsofotherfunctionsmayormaynotbetreatedsimilarlytoordinaryarguments.Similar issuesarisewithotheroperatorswhichhavesideeffects,suchastheassignmentoperatorsandthe incrementanddecrementoperators. InorderthattheefficiencyofConaparticularmachinenotbeundulycompromised,theC languageleavestheorderofevaluationofcomplicatedexpressionsuptothelocalcompiler,and, infact,thevariousCcompilershaveconsiderabledifferencesintheorderinwhichtheywillevaluatecomplicatedexpressions.Inparticular,ifanyvariableischangedbyasideeffect,andalso usedelsewhereinthesameexpression,theresultisexplicitlyundefined. Lintchecksfortheimportantspecialcasewhereasimplescalarvariableisaffected.For example,thestatement a[i]=b[i++]; willdrawthecomplaint: warning:ievaluationorderundefined Implementation Lintconsistsoftwoprogramsandadriver.ThefirstprogramisaversionofthePortableC Compiler4,5whichisthebasisoftheIBM370,Honeywell6000,andInterdata8/32Ccompilers. Thiscompilerdoeslexicalandsyntaxanalysisontheinputtext,constructsandmaintainssymbol 4 5 -7-tables,andbuildstreesforexpressions.Insteadofwritinganintermediatefilewhichispassedto acodegenerator,astheothercompilersdo,lintproducesanintermediatefilewhichconsistsof linesofasciitext.Eachlinecontainsanexternalvariablename,anencodingofthecontextin whichitwasseen(use,definition,declaration,etc.),atypespecifier,andasourcefilenameand linenumber.Theinformationaboutvariableslocaltoafunctionorfileiscollectedbyaccessing thesymboltable,andexaminingtheexpressiontrees. Commentsaboutlocalproblemsareproducedasdetected.Theinformationaboutexternal namesiscollectedontoanintermediatefile.Afterallthesourcefilesandlibrarydescriptionshave beencollected,theintermediatefileissortedtobringallinformationcollectedaboutagiven externalnametogether.Thesecond,rathersmall,programthenreadsthelinesfromtheintermediatefileandcomparesallofthedefinitions,declarations,andusesforconsistency. Thedrivercontrolsthisprocess,andisalsoresponsibleformakingtheoptionsavailableto bothpassesoflint. Portability ContheHoneywellandIBMsystemsisused,inpart,towritesystemcodeforthehost operatingsystem.ThismeansthattheimplementationofCtendstofollowlocalconventions ratherthanadherestrictlytoUNIX◯rsystemconventions.Despitethesedifferences,manyCprogramshavebeensuccessfullymovedtoGCOSandthevariousIBMinstallationswithlittleeffort. Thissectiondescribessomeofthedifferencesbetweentheimplementations,anddiscussesthelint featureswhichencourageportability. UninitializedexternalvariablesaretreateddifferentlyindifferentimplementationsofC. Supposetwofilesbothcontainadeclarationwithoutinitialization,suchas inta; outsideofanyfunction.TheUNIXloaderwillresolvethesedeclarations,andcauseonlyasingle wordofstoragetobesetasidefora.UndertheGCOSandIBMimplementations,thisisnotfeasible(forvariousstupidreasons!)soeachsuchdeclarationcausesawordofstoragetobeset asideandcalleda.Whenloadingorlibraryeditingtakesplace,thiscausesfatalconflictswhich preventtheproperoperationoftheprogram.Iflintisinvokedwiththe−pflag,itwilldetect suchmultipledefinitions. Arelateddifficultycomesfromtheamountofinformationretainedaboutexternalnames duringtheloadingprocess.OntheUNIXsystem,externallyknownnameshavesevensignificant characters,withtheupper/lowercasedistinctionkept.OntheIBMsystems,thereareeightsignificantcharacters,butthecasedistinctionislost.OnGCOS,thereareonlysixcharacters,ofa singlecase.ThisleadstosituationswhereprogramsrunontheUNIXsystem,butencounter loaderproblemsontheIBMorGCOSsystems.Lint−pcausesallexternalsymbolstobe mappedtoonecaseandtruncatedtosixcharacters,providingaworst-caseanalysis. Anumberofdifferencesariseintheareaofcharacterhandling:charactersintheUNIXsystemareeightbitascii,whiletheyareeightbitebcdicontheIBM,andninebitasciionGCOS. Moreover,characterstringsgofromhightolowbitpositions(‘‘lefttoright’’)onGCOSandIBM, andlowtohigh(‘‘righttoleft’’)onthePDP-11.Thismeansthatcodeattemptingtoconstruct stringsoutofcharacterconstants,orattemptingtousecharactersasindicesintoarrays,mustbe lookedatwithgreatsuspicion.Lintisoflittlehelphere,excepttoflagmulti-charactercharacter constants. Ofcourse,thewordsizesaredifferent!Thiscauseslesstroublethanmightbeexpected,at leastwhenmovingfromtheUNIXsystem(16bitwords)totheIBM(32bits)orGCOS(36bits). Themainproblemsarelikelytoariseinshiftingormasking.Cnowsupportsabit-fieldfacility, whichcanbeusedtowritemuchofthiscodeinareasonablyportableway.Frequently,portabilityofsuchcodecanbeenhancedbyslightrearrangementsincodingstyle.Manyoftheincompatibilitiesseemtohavetheflavorofwriting -8-x&=0177700; toclearthelowordersixbitsofx.ThissufficesonthePDP-11,butfailsbadlyonGCOSand IBM.Ifthebitfieldfeaturecannotbeused,thesameeffectcanbeobtainedbywriting x&=∼077; whichwillworkonallthesemachines. TherightshiftoperatorisarithmeticshiftonthePDP-11,andlogicalshiftonmostother machines.Toobtainalogicalshiftonallmachines,theleftoperandcanbetypedunsigned. CharactersareconsideredsignedintegersonthePDP-11,andunsignedontheothermachines. ThispersistenceofthesignbitmaybereasonablyconsideredabuginthePDP-11hardware whichhasinfiltrateditselfintotheClanguage.Iftherewereagoodwaytodiscovertheprograms whichwouldbeaffected,Ccouldbechanged;inanycase,lintisnohelphere. Theabovediscussionmayhavemadetheproblemofportabilityseembiggerthanitinfact is.Theissuesinvolvedherearerarelysubtleormysterious,atleasttotheimplementorofthe program,althoughtheycaninvolvesomeworktostraightenout.Themostseriousbartothe portabilityofUNIXsystemutilitieshasbeentheinabilitytomimicessentialUNIXsystemfunctions ontheothersystems.Theinabilitytoseektoarandomcharacterpositioninatextfile,orto establishapipebetweenprocesses,hasinvolvedfarmorerewritinganddebuggingthananyofthe differencesinCcompilers.Ontheotherhand,linthasbeenveryhelpfulinmovingtheUNIX operatingsystemandassociatedutilityprogramstoothermachines. ShuttingLintUp Thereareoccasionswhentheprogrammerissmarterthanlint.Theremaybevalidreasons for‘‘illegal’’typecasts,functionswithavariablenumberofarguments,etc.Moreover,asspecified above,theflowofcontrolinformationproducedbylintoftenhasblindspots,causingoccasional spuriousmessagesaboutperfectlyreasonableprograms.Thus,somewayofcommunicatingwith lint,typicallytoshutitup,isdesirable. Theformwhichthismechanismshouldtakeisnotatallclear.Newkeywordswouldrequire currentandoldcompilerstorecognizethesekeywords,ifonlytoignorethem.Thishasboth philosophicalandpracticalproblems.Newpreprocessorsyntaxsuffersfromsimilarproblems. Whatwasfinallydonewastocauseanumberofwordstoberecognizedbylintwhenthey wereembeddedincomments.Thisrequiredminimalpreprocessorchanges;thepreprocessorjust hadtoagreetopasscommentsthroughtoitsoutput,insteadofdeletingthemashadbeenpreviouslydone.Thus,lintdirectivesareinvisibletothecompilers,andtheeffectonsystemswiththe olderpreprocessorsismerelythatthelintdirectivesdon’twork. Thefirstdirectiveisconcernedwithflowofcontrolinformation;ifaparticularplaceinthe programcannotbereached,butthisisnotapparenttolint,thiscanbeassertedbythedirective /*NOTREACHED*/ attheappropriatespotintheprogram.Similarly,ifitisdesiredtoturnoffstricttypechecking forthenextexpression,thedirective /*NOSTRICT*/ canbeused;thesituationrevertstothepreviousdefaultafterthenextexpression.The−vflag canbeturnedonforonefunctionbythedirective /*ARGSUSED*/ Complaintsaboutvariablenumberofargumentsincallstoafunctioncanbeturnedoffbythe directive /*VARARGS*/ precedingthefunctiondefinition.Insomecases,itisdesirabletocheckthefirstseveral -9-arguments,andleavethelaterargumentsunchecked.Thiscanbedonebyfollowingthe VARARGSkeywordimmediatelywithadigitgivingthenumberofargumentswhichshouldbe checked;thus, /*VARARGS2*/ willcausethefirsttwoargumentstobechecked,theothersunchecked.Finally,thedirective /*LINTLIBRARY*/ attheheadofafileidentifiesthisfileasalibrarydeclarationfile;thistopicisworthasectionby itself. LibraryDeclarationFiles Lintacceptscertainlibrarydirectives,suchas −ly andteststhesourcefilesforcompatibilitywiththeselibraries.Thisisdonebyaccessinglibrary descriptionfileswhosenamesareconstructedfromthelibrarydirectives.Thesefilesallbegin withthedirective /*LINTLIBRARY*/ whichisfollowedbyaseriesofdummyfunctiondefinitions.Thecriticalpartsofthesedefinitions arethedeclarationofthefunctionreturntype,whetherthedummyfunctionreturnsavalue,and thenumberandtypesofargumentstothefunction.TheVARARGSandARGSUSEDdirectives canbeusedtospecifyfeaturesofthelibraryfunctions. Lintlibraryfilesareprocessedalmostexactlylikeordinarysourcefiles.Theonlydifference isthatfunctionswhicharedefinedonalibraryfile,butarenotusedonasourcefile,drawno complaints.Lintdoesnotsimulateafulllibrarysearchalgorithm,andcomplainsifthesource filescontainaredefinitionofalibraryroutine(thisisafeature!). Bydefault,lintcheckstheprogramsitisgivenagainstastandardlibraryfile,whichcontainsdescriptionsoftheprogramswhicharenormallyloadedwhenaCprogramisrun.When the-pflagisineffect,anotherfileischeckedcontainingdescriptionsofthestandardI/Olibrary routineswhichareexpectedtobeportableacrossvariousmachines.The-nflagcanbeusedto suppressalllibrarychecking. Bugs,etc. Lintwasadifficultprogramtowrite,partiallybecauseitiscloselyconnectedwithmatters ofprogrammingstyle,andpartiallybecauseusersusuallydon’tnoticebugswhichcauselintto misserrorswhichitshouldhavecaught.(Bycontrast,iflintincorrectlycomplainsaboutsomethingthatiscorrect,theprogrammerreportsthatimmediately!) Anumberofareasremaintobefurtherdeveloped.Thecheckingofstructuresandarraysis ratherinadequate;sizeincompatibilitiesgounchecked,andnoattemptismadetomatchupstructureanduniondeclarationsacrossfiles.Somestrictercheckingoftheuseofthetypedefis clearlydesirable,butwhatcheckingisappropriate,andhowtocarryitout,isstilltobedetermined. LintsharesthepreprocessorwiththeCcompiler.Atsomepointitmaybeappropriatefor aspecialversionofthepreprocessortobeconstructedwhichchecksforthingssuchasunused macrodefinitions,macroargumentswhichhavesideeffectswhicharenotexpandedatall,orare expandedmorethanonce,etc. Thecentralproblemwithlintisthepackagingoftheinformationwhichitcollects.There aremanyoptionswhichserveonlytoturnoff,orslightlymodify,certainfeatures.Therearepressurestoaddevenmoreoftheseoptions.

-10-Inconclusion,itappearsthatthegeneralnotionofhavingtwoprogramsisagoodone.The compilerconcentratesonquicklyandaccuratelyturningtheprogramtextintobitswhichcanbe run;lintconcentratesonissuesofportability,style,andefficiency.Lintcanaffordtobewrong, sinceincorrectnessandover-conservatismaremerelyannoying,notfatal.Thecompilercanbe fastsinceitknowsthatlintwillcoveritsflanks.Finally,theprogrammercanconcentrateatone stageoftheprogrammingprocesssolelyonthealgorithms,datastructures,andcorrectnessofthe program,andthenlaterretrofit,withtheaidoflint,thedesirablepropertiesofuniversalityand portability.

-11-Appendix:CurrentLintOptions Thecommandcurrentlyhastheform lint[−options]files...library-descriptors... Theoptionsare hPerformheuristicchecks pPerformportabilitychecks vDon’treportunusedarguments uDon’treportunusedorundefinedexternals bReportunreachablebreakstatements. xReportunusedexternaldeclarations aReportassignmentsoflongtointorshorter. cComplainaboutquestionablecasts nNolibrarycheckingisdone sSameash(forhistoricalreasons)