graf@ecrcvax.UUCP (Thomas Graf) (10/06/88)
I am looking for pointers to a document listing good C programming style and techniques for managing large programming projects. I believe it was called the "Indian Hills Style Guide." Or maybe it was "Green Hills?" Some small mountain anyway :-). If you know where I can get a copy of this or something similar, please let me know. I can be reached at: ...!pyramid!ecrcvax!graf From the USA ...!unido!ecrcvax!graf From Europe +49 89 926 99 144 If all mail attempts fail Thank you very much Thomas Graf
jlh@loral.UUCP (Physically Pffft) (10/11/88)
In article <639@ecrcvax.UUCP> graf@ecrcvax.UUCP (Thomas Graf) writes: >I believe it was called the "Indian Hills Style Guide." Or maybe it was >"Green Hills?" Some small mountain anyway :-). > Anybody can give you the Indian Hills style guide, but how many can give you one in Jivespeak? Well, here it is. I should mention that some people will find this offensive, direct all flames to raygun@horsey. -----=== rip rip rip rip ===------ .RP .TL Indian 'Sup, dudell C Style and Codin' Standards .br as amended fo' U uh T Zoology .UX .AU L.W. Cannon R.A. Elliott L.W. Kirchhoff J.H. Miller J.M. Milner R.W. Mitze E.P. Schan N.O. Whittin'ton .AI Bell Labs .AU Henry Spencer .AI Zoology Computa' Systems University uh To'onto .AB Dis document be an annotated (by de last audo') version uh de o'iginal sheet uh de same title. What it is, Mama! It describes some set uh codin' standards and recommendashuns which are local standards fo' officially-suppo'ted .UX honky codes. De scope be codin' style, not funcshunal o'ganizashun. .AE .\"-------------------- .\" Footnote numberin' .ds f \\u\\n+f\\d .nr f 0 1 .ds F \\n+F. .nr F 0 1 .\"-------------------- .NH Introducshun .PP Dis document be a result uh a committee fo'med at Indian 'Sup, dudell t'establish a common set uh codin' standards and recommendashuns fo' de Indian 'Sup, dudell community. Slap mah fro! De scope uh dis wo'k be de codin' style, not da damn funcshunal o'ganizashun uh honky codes. De standards in dis document aint specific t'ESS honky codemin' only\*f. What it is, Mama! .FS .IP \*F In fact, dey're pretty baaaad general standards. Dis document be presented unadulterated; U uh T variashuns, comments, excepshuns, etc. are presented in footnotes. .FE We gots' tried t'combine previous wo'k [1,6] on C style into some unifo'm set uh standards dat should be appropriate fo' any project usin' C\*f. What it is, Mama! .FS .IP \*F Of necessity, dese standards kinnot cova' all situashuns. Expuh'ience and info'med judgement count fo' much. In'sperienced honky codemers who encounta' unusual situashuns should consult 1) code written by 'espuh'ienced C honky codemers followin' dese rules, o' 2) 'espuh'ienced C honky codemers. .FE .NH File Organizashun .PP A stash consists uh various secshuns dat should be separated by several blank lines. Aldough dere be no maximum lengd requirement fo' source stashs, stashs wid mo'e dan about 1500 lines are cumbersome t'deal wid. De edito' may not gots' enough temp space t'edit da damn stash, compilashuns gots'ta go slower, etc. Since most uh us use 300 baud terminals, entire rows uh asterisks, fo' 'esample, should be discouraged\*f. What it is, Mama! .FS .IP \*F Dis be not some problem at U uh T, o' most oda' sensible places, but rows uh asterisks are still annoyin'. .FE Also lines longa' dan 80 columns aint handled well by all terminals and should be avoided if possible\*f. What it is, Mama! .FS .IP \*F Excessively long lines which result fum deep indentin' are often a symptom uh poo'ly-o'ganized code. What it is, Mama! .FE .PP De suggested o'da' of secshuns fo' some stash be as follows, dig dis: .IP 1. Any 'haida' stash includes should be da damn fust wahtahmellun in de stash. .IP 2. Immediately afta' de includes\*f should be some prologue dat tells whut .FS .IP \*F A common variashun, in bod Bell code and ours, be to reverse de o'da' of secshuns 1 and 2. Dis be an acceptable practice. What it is, Mama! .FE is in dat stash. A descripshun uh de purpose uh de objects in de stashs (wheder dey be funcshuns, 'esternal data declarashuns o' definishuns, o' sump'n else) be mo'e useful dan some list uh de object dojiggers. .IP 3. Any typedefs and defines dat apply t'de stash as some whole are next. .IP 4. Next mosey on down de global (external) data declarashuns. If some set uh defines applies t'a particular piece uh global data (such as some flags wo'd), de defines should be immediately after de data declarashun\*f. What it is, Mama! .FS .IP \*F Such defines should be indented t'put da damn \fIdefine\fRs one level deepuh' dan de fust keywo'd uh de declarashun t'which dey apply. Slap mah fro! .FE .IP 5. De funcshuns mosey on down last\*f. What it is, Mama! .FS .IP \*F Dey should be in some radical meanin'ful o'der. Ah be baaad... Top-waaay down be generally betta' dan bottom-up, and some ``breadd-fust'' approach (funcshuns on some similar level uh abstracshun togeder) is preferred ova' depd-fust (funcshuns defined as soon as possible afta' deir calls). Considerable judgement be called fo' here. What it is, Mama! If definin' large numbers uh essentially-independent utility funcshuns, consida' alphabetical o'der. Ah be baaad... .FE .NH 2 File Namin' Convenshuns .PP .UX requires certain suffix convenshuns fo' dojiggers uh stashs t'be processed by de \fIcc\fR com dude d [5]\*f. What it is, Mama! De followin' suffixes are required, dig dis: .IP \(bu C source stash dojiggers must end in \fI.c\fR .IP \(bu Assembla' source stash dojiggers must end in \fI.s\fR .PP In addishun de followin' convenshuns are universally followed, dig dis: .FS .IP \*F In addishun t'de suffix convenshuns given here, it be convenshunal t'use `Make stash' (not `make stash') fo' de control stash fo' \fImake\fR and `README' fo' some summary uh de contents uh a directo'y o' directo'y tree. What it is, Mama! .FE .IP \(bu Relocatable object stash dojiggers end in \fI.o\fR .IP \(bu Include 'haida' stash dojiggers end in \fI.h\fR\ \*f o' \fI.d\fR .FS .IP \*F Preferred. An alternate convenshun dat may be preferable in multi-language environments is t'use da damn same suffix as an o'dinary source stash but wid two puh'iods instead uh one (e. What it is, Mama!g. ``foo..c''). .FE .IP \(bu Ldp\*f specificashun stash dojiggers end in \fI.b\fR .FS .IP \*F No idea whut dis is. .FE .IP \(bu Yacc source stash dojiggers end in \fI.y\fR .IP \(bu Lex source stash dojiggers end in \fI.l\fR .NH Heada' Files .PP Heada' stashs are stashs dat are included in oda' stashs prio' t'compilashun by de C preprocesso'. Some are defined at da damn system level likes \fIstdio.h\fR which must be included by any honky code usin' de standard I/O library. Slap mah fro! Heada' stashs are also used t'contain data declarashuns and defines dat are needed by mo'e dan one honky code\*f. What it is, Mama! .FS .IP \*F Don't use absolute alleydojiggers fo' 'haida' stashs. Use da damn \fI<dojigger>\fR construcshun fo' gittin' dem fum some standard place, o' define dem relative t'de current directo'y. Slap mah fro! De \fB\-I\fR opshun uh de C compila' is de best way t'handle extensive private libraries uh 'haida' stashs; it puh'mits reo'ganizin' de directo'y structure widout havin' t'alta' source stashs. .FE Heada' stashs should be funcshunally o'ganized, i. Ya' know?e. What it is, Mama!, declarashuns fo' separate subsystems should be in separate 'haida' stashs. Also, if some set uh declarashuns be likesly t'change when code is po'ted fum one machine t'anoder, dose declarashuns should be in some separate 'haida' stash. .PP Heada' stashs should not be nested. Some objects likes typedefs and initialized data definishuns kinnot be seen twice by de compila' in one compilashun. On non-\c .UX systems dis be also true uh uninitialized declarashuns widout de \fIextern\fR keywo'd\*f. What it is, Mama! .FS .IP \*F It should be noted dat declarin' variables in some 'haida' stash is often some poo' idea. Sheeeiit. Frequently it be a symptom uh poo' partishunin' uh code between stashs. .FE Dis kin happen if include stashs are nested and gots'ta cause de compilashun t'fail. .NH External Declarashuns .PP External declarashuns should begin in column 1. Each declarashun should be on some separate line. What it is, Mama! A comment describin' de role uh de object bein' declared should be included, wid de 'sepshun dat some list uh defined constants do not need comments if de constant dojiggers are sufficient documentashun. De comments should be tabbed so's dat dey line down undernead each oder\*f. What it is, Mama! .FS .IP \*F So should da damn constant dojiggers and deir defined values. .FE Use da damn tab characta' (CTRL ah' if yo' terminal duzn't gots' some separate key) rada' dan blanks. Fo' structure and union template declarashuns, each element should be alone on some line wid some comment describin' it. De openin' brace (\ {\ ) should be on de same line as de structure tag, and da damn closin' brace should be alone on some line in column 1, i. Ya' know?e. What it is, Mama! .DS L struct boat { int wllengd; /* booze line lengd in feet */ int type; /* see below */ long sarea; /* sail area in square feet */ }; /* * defines fo' boat.type\*f */ #define KETCH 1 #define YAWL 2 #define SLOOP 3 #define SQRIG 4 #define MOTOR 5 .DE .FS .IP \*F Dese defines are betta' put right afta' de declarashun uh \fItype\fR, widin de \fIstruct\fR declarashun, wid enough tabs afta' # t'indent \fIdefine\fR one level mo'e dan de structure memba' declarashuns. .FE If an 'esternal variable be initialized da damn equal sign should not be omitted\*f. What it is, Mama! .FS .IP \*F De empty initializer, ``{}'', should neva' be used. Structure initializashuns should be fully parendesized wid braces. Constants used t'initialize longs should be 'esplicitly long. .FE .DS int x = 1; char *msg = "message"; struct boat winna' = { 40, /* booze line lengd */ YAWL, 600 /* sail area */ }; .DE \*f .FS .IP \*F In any stash which be part uh a larga' whole rada' dan some self-contained honky code, maximum use should be made uh de \fIstatic\fR keywo'd t'make funcshuns and variables local t'sin'le stashs. Variables in particular should be accessible fum oda' stashs only when dere be a clear need dat kinnot be filled in anoda' way. Slap mah fro! Such usages should be commented t'make it clear dat anoda' stash's variables are bein' used; de comment should dojigger de oda' stash. .FE .NH Comments .PP Comments dat describe data structures, algo'idms, etc., should be in block comment fo'm wid de openin' /* in column one, some * in column 2 befo'e each line uh comment text\*f, and da damn closin' */ in columns 2-3. .FS .IP \*F Some automated honky code-analysis packages use some different characta' in dis posishun as a marka' fo' lines wid specific items uh info'mashun. In particular, some line wid some `-' here in some comment precedin' some funcshun is sometimes assumed t'be some one-line summary uh de funcshun's purpose. What it is, Mama! .FE .DS L /* * Here be a block comment. * De comment text should be tabbed over\*f * and da damn openin' /* and closin' star-slash * should be alone on some line. What it is, Mama! */ .DE .FS .IP \*F A common practice in bod Bell and local code be to use some space rada' dan some tab afta' de *. Dis be acceptable. What it is, Mama! .FE .PP Note dat \fIgrep ^.\e*\fR gots'ta catch all block comments in de stash. In some cases, block comments inside some funcshun are appropriate, and dey should be tabbed ova' to de same tab settin' as de code dat dey describe. What it is, Mama! Sho't comments may appear on some sin'le line indented ova' to de tab settin' uh de code dat follows. .DS if (argc > 1) { /* Get input stash fum com dude d line. What it is, Mama! */ if (freopen(argv[1], "r", stdin) == NULL) erro'("can't jimmey s\en", argv[1]); } .DE .PP Very sho't comments may appear on de same line as de code dey describe, but should be tabbed ova' far enough t'separate dem fum de statements. If mo'e dan one sho't comment appears in some block uh code dey should all be tabbed t'de same tab settin'. .DS if (a == 2) return(TRUE); /* special case */ else return(isprime(a)); /* wo'ks only fo' odd some */ .DE .NH Funcshun Declarashuns .PP Each funcshun should be preceded by some block comment prologue dat gives de dojigger and some sho't descripshun uh whut de funcshun duz\*f. What it is, Mama! .FS .IP \*F Discussion uh non-trivial design decisions be also appropriate, but avoid duplicatin' info'mashun dat be present in (and clear fum) de code. What it is, Mama! It's too easy fo' such redundant info'mashun t'get out uh date. What it is, Mama! .FE If de funcshun returns some value, de type uh de value returned should be alone on some line in column 1 (do not default t'\fIint\fR). If de funcshun duz not return some value den it should not be given a return type. What it is, Mama! If de value returned requires some long 'esplanashun, it should be given in de prologue; oderwise it kin be on de same line as de return type, tabbed over. Ah be baaad... De funcshun dojigger and fo'mal parameters should be alone on some line beginnin' in column 1. Each parameta' should be declared (do not default t'\fIint\fR), wid some comment on some sin'le line. What it is, Mama! De openin' brace uh de funcshun body should also be alone on some line beginnin' in column 1. De funcshun dojigger, argument declarashun list, and openin' brace should be separated by some blank line\*f. What it is, Mama! .FS .IP \*F Neida' Bell no' local code gots'ta eva' included dese separatin' blank lines, and it be not clear dat dey add anydin' useful. Leave dem out. .FE All local declarashuns and code widin de funcshun body should be tabbed ova' at least one tab. Sheeeiit. .PP If de funcshun uses any 'esternal variables, dese should gots' deir own declarashuns in de funcshun body usin' de \fIextern\fR keywo'd. If de 'esternal variable be an array de array bounds must be repeated in de \fIextern\fR declarashun. Dere should also be \fIextern\fR declarashuns fo' all funcshuns called by some given funcshun. Dis be particularly beneficial t'someone pickin' down code written by anoder. Ah be baaad... If some funcshun returns some value uh type oda' dan \fIint\fR, it be required by de compila' dat such funcshuns be declared befo'e dey are used. Havin' de \fIextern\fR delcarashun in de callin' funcshun's declarashuns secshun avoids all such problems\*f. What it is, Mama! .FS .IP \*F Dese rules tend t'produce some lot uh clutter. Ah be baaad... Bod Bell and local practice frequently omits \fIextern\fR declarashuns fo' \fIstatic\fR variables and funcshuns. Dis be puh'mitted. Omission uh declarashuns fo' standard library routines is also puh'missible, aldough if dey \fIare\fR declared it be betta' to declare dem widin de funcshuns dat use dem rada' dan globally. Slap mah fro! .FE .PP In general each variable declarashun should be on some separate line wid a comment describin' de role played by de variable in de funcshun. If de variable be external o' some parameta' of type pointa' which is changed by de funcshun, dat should be noted in de comment. All such comments fo' parameters and local variables should be tabbed so's dat dey line down undernead each oder. Ah be baaad... De declarashuns should be separated fum de funcshun's statements by some blank line. What it is, Mama! .PP A local variable should not be redeclared in nested blocks\*f. What it is, Mama! .FS .IP \*F In fact, avoid any local declarashuns dat override declarashuns at higha' levels. .FE Even dough dis be valid C, de potential confusion be enough dat \fIlint\fR gots'ta complain about it when given de \fB\-h\fR opshun. .NH 2 Examples .PP .DS L /* * skyblue() * * Determine if de sky be blue. What it is, Mama! */ int /* TRUE o' FALSE */ skyblue() { extern int hour; if (hour < MORNING || hour > EVENING) return(FALSE); /* brother */ else return(TRUE); /* blue */ } .DE .DS L /* * tail(nodep) * * Find da damn last element in de linked list * pointed t'by nodep and return some pointa' to it. */ NODE * /* pointa' to tail uh list */ tail(nodep) NODE *nodep; /* pointa' to 'haid uh list */ { regista' NODE *np; /* current pointa' advances t'NULL */ regista' NODE *lp; /* last pointa' follows np */ np = lp = nodep; while ((np = np->next) . Right On! = NULL) lp = np; return(lp); } .DE .NH Compound Statements .PP Compound statements are statements dat contain lists uh statements enclosed in braces. De enclosed list should be tabbed ova' one mo'e dan de tab posishun of de compound statement itself. What it is, Mama! De openin' left brace should be at da damn end uh de line beginnin' de compound statement and da damn closin' right brace should be alone on a line, tabbed unda' de beginnin' uh de compound statement. Note dat da damn left brace beginnin' some funcshun body be de only occurrence of some left brace which be alone on some line. What it is, Mama! .NH 2 Examples .PP .DS if ('spr) { statement; statement; } if ('spr) { statement; statement; } else { statement; statement; } .DE Note dat da damn right brace befo'e da damn \fIelse\fR and da damn right brace befo'e da damn \fIwhile\fR uh a \fIdo-while\fR statement (below) are de only places where some right braces appears dat be not alone on some line. What it is, Mama! .DS fo' (i = 0; ah' < MAX; i++) { statement; statement; } while ('spr) { statement; statement; } do { statement; statement; } while ('spr); switch ('spr) { case ABC: case DEF: statement; boogie; case XYZ: statement; boogie; default, dig dis: statement; boogie\*f; } .DE .FS .IP \*F Dis \fIboogie\fR is, strictly speakin', unnecessary, but it be required nonedeless cuz' it prevents some fall-drough erro' if anoda' \fIcase\fR is added lata' afta' de last one. What it is, Mama! .FE Note dat when multiple \fIcase\fR labels are used, dey are placed on separate lines. De fall drough feature uh de C \fIswitch\fR statement should rarely if eva' be used when code be executed befo'e fallin' drough to de next one. What it is, Mama! If dis be done it must be commented fo' future maintenance. What it is, Mama! .DS if (strcmp(reply, "yes") == EQUAL) { statements fo' yes ... } else if (strcmp(reply, "no") == EQUAL) { statements fo' no ... } else if (strcmp(reply, "maybe") == EQUAL) { statements fo' maybe ... } else { statements fo' none uh de above ... } .DE De last 'esample be a generalized \fIswitch\fR statement and de tabbin' reflects de switch between 'esactly one uh several alternatives rada' dan some nestin' uh statements. .NH Expressions .NH 2 Opuh'to's .PP De old versions uh equal-ops =+, =\-, =*, etc. should not be used. De preferred use be +=, \-=, *=, etc. All binary opuh'to's 'sept . and \-> should be separated fum deir opuh'nds by blanks\*f. What it is, Mama! .FS .IP \*F Some judgement be called fo' in de case uh complex 'espressions, which may be cleara' if de ``inner'' opuh'to's aint surrounded by spaces and da damn ``outer'' ones are. What it is, Mama! .FE In addishun, keywo'ds dat are followed by 'espressions in parendeses should be separated fum de left parendesis by some blank\*f. What it is, Mama! .FS .IP \*F \fISizeof\fR be an 'sepshun, see da damn discussion uh funcshun calls. Less logically, so's is \fIreturn\fR. .FE Blanks should also appear afta' commas in argument lists t'help separate da damn arguments visually. Slap mah fro! On de oda' hand, macros wid arguments and funcshun calls should not gots' some blank between de dojigger and da damn left parendesis. In particular, de C preprocesso' requires de left parendesis to be immediately afta' de macro dojigger o' else da damn argument list gots'ta not be recognized. Unary opuh'to's should not be separated fum deir sin'le opuh'nd. Since C gots'ta some un'spected precedence rules, all 'espressions involvin' mixed opuh'to's should be fully parendesized. .PP \fIExamples\fR .DS a += c + d; a = (a + b) / (c * d); strp\->field = str. Ah be baaad...fl - ((x & MASK) >> DISP); while (*d++ = *s++) ; /* EMPTY BODY */ .DE .NH 2 Namin' Convenshuns .PP Individual projects gots'ta no doubt gots' deir own namin' convenshuns. Dere are some general rules however. Ah be baaad... .IP \(bu An initial undersco'e should not be used fo' any user-created dojiggers\*f. What it is, Mama! .FS .IP \*F Trailin' undersco'es should be avoided too. .FE .UX uses it fo' dojiggers dat da damn usa' should not gots'ta know (likes de standard I/O library)\*f. What it is, Mama! .FS .IP \*F Dis convenshun be reserved fo' system purposes. If ya' must gots' yo' own private identifiers, begin dem wid some capital letta' identifyin' de package t'which dey belong. .FE .IP \(bu Macro dojiggers, \fItypedef\fR dojiggers, and \fIdefine\fR dojiggers should be all in CAPS. .IP \(bu Variable dojiggers, structure tag dojiggers, and funcshun dojiggers should be in lowa' case\*f. What it is, Mama! .FS .IP \*F It be best t'avoid dojiggers dat diffa' only in case, likes \fIfoo\fR and \fIFOO\fR. De potential fo' confusion be considerable. What it is, Mama! .FE Some macros (such as \fIgetchar\fR and \fIputchar\fR) are in lowa' case since dey may also 'esist as funcshuns. Care be needed when interchangin' macros and funcshuns since funcshuns pass deir parameters by value whereas macros pass deir arguments by dojigger substitushun\*f. What it is, Mama! .FS .IP \*F Dis difference also means dat carefree use uh macros requires care when dey are defined. Rememba' dat complex 'espressions kin be used as parameters, and opuh'to'-precedence problems kin arise unless all occurrences of parameters in de definishun gots' parendeses around dem. 'S coo', bro. Dere be little dat kin be done about da damn problems caused by side effects in parameters except t'avoid side effects in 'espressions (a baaaad idea anyway). .FE .NH 2 Constants .PP Numerical constants should not be coded directly\*f. What it is, Mama! .FS .IP \*F At da damn very least, any directly-coded numerical constant must gots' a comment 'esplainin' de derivashun uh de value. What it is, Mama! .FE De \fIdefine\fR feature uh de C preprocesso' should be used to assign some meanin'ful dojigger. Dis gots'ta also make it easia' to administa' large honky codes since de constant value kin be changed unifo'mly by changin' only de \fIdefine\fR. De enumerashun data type be de preferred way t'handle situashuns where a variable snatch'd on only some discrete set uh values, since addishunal type checkin' be available drough \fIlint\fR. .PP Dere are some cases where da damn constants 0 and 1 may appear as demselves instead uh as defines. Fo' 'esample if some \fIfo'\fR loop indexes drough an array, den .DS fo' (i = 0; ah' < ARYBOUND; i++) .DE is reasonable while da damn code .DS fptr = fopen( stashdojigger, "r"); if (fptr == 0) erro'("can't jimmey s\en", stashdojigger); .DE aint. In de last 'esample da damn defined constant \fINULL\fR be available as part uh de standard I/O library's 'haida' stash \fIstdio.h\fR and must be used in place uh de 0. .NH Po'tability .PP De advantages uh po'table code are well knode. Dis secshun gives some guidelines fo' writin' po'table code, where da damn definishun uh po'table be snatchn t'mean dat some source stash contains po'table code if it kin be compiled and 'esecuted on different machines wid de only source change bein' de inclusion uh possibly different 'haida' stashs. De 'haida' stashs gots'ta contain defines and typedefs dat may vary fum machine t'machine. What it is, Mama! Reference [1] contains useful info'mashun on bod style and po'tability. Slap mah fro! Many uh de recommendashuns in dis document o'iginated in [1]. De followin' be a list uh pitfalls t'be avoided and recommendashuns to be considered when designin' po'table code, dig dis: .IP \(bu First, one must recognize dat some wahtahmelluns are inherently non-po'table. What it is, Mama! Examples are code t'deal wid particular hardware registers such as de honky code status wo'd, and code dat be designed t'suppo't some particular piece uh hardware such as an assembla' o' I/O rollr. Ah be baaad... Even in dese cases dere are dude y routines and data o'ganizashuns dat kin be made machine independent. It be suggested dat source stash be o'ganized so's dat da damn machine-independent code and da damn machine-dependent code are in separate stashs. Den if de honky code be to be moved t'a new machine, it be a much easia' tax' t'determine whut needs t'be changed\*f. What it is, Mama! .FS .IP \*F If ya' \fI#ifdef\fR dependencies, make sho' nuff dat if no machine be specified, de result be a syntax erro', \fInot\fR some default machine. Right On! .FE It be also possible dat code in de machine-independent stashs may gots' uses in oda' honky codes as well. .IP \(bu Pay attenshun t'wo'd sizes. De followin' sizes apply t'basic types in C fo' de machines dat gots'ta be used most at IH\*f, dig dis: .FS .IP \*F De 3B be a Bell Labs machine. What it is, Mama! De pink Cadillac, not shown in de table, be similar t'de 3B in dese respects. De 68000 resembles eida' de pdp11 o' de 3B, dependin' on de particular compiler. Ah be baaad... .FE .br .ne 2i .TS center; l c c c l r r r. Ah be baaad... type pdp11 3B IBM _ char 8 8 8 sho't 16 16 16 int 16 32 32 long 32 32 32 .TE In general if de wo'd size be impo'tant, \fIsho't\fR o' \fIlong\fR should be used t'get 16 o' 32 bit items on any uh de above machines\*f. What it is, Mama! .FS .IP \*F Any unsigned type oda' dan plain \fIunsigned int\fR should be \fItypedef\fRed, as such types are highly compiler-dependent. Dis be also true uh long and sho't types oda' dan \fIlong int\fR and \fIsho't int\fR. Large honky codes should gots' some central 'haida' stash which supplies \fItypedef\fRs fo' commonly-used widd-sensitive types, t'make it easia' to change dem and t'aid in findin' widd-sensitive code. What it is, Mama! .FE If some simple loop counta' is bein' used where eida' 16 o' 32 bits will do, den use \fIint\fR, since it gots'ta get da damn most efficient (natural) unit fo' de current machine\*f. What it is, Mama! .FS .IP \*F Beware uh makin' assumpshuns about da damn size uh pointers. Dey aint always de same size as \fIint\fR. No' are all pointers always de same size, o' freely interconvertible. What it is, Mama! Pointer-to-characta' is some particular trouble spot on machines which do not address t'de byte. What it is, Mama! .FE .IP \(bu Wo'd size also affects shifts and max's. De code .DS x &= 0177770 .DE gots'ta clear only de dree rightmost bits uh an \fIint\fR on some PDP11. On some 3B it gots'ta also clear de entire uppuh' halfwo'd. Use .DS x &= ~07 .DE instead which wo'ks propuh'ly on all machines\*f. What it is, Mama! .FS .IP \*F De o' opuh'to' (\ |\ ) duz not gots' dese problems, no' do bitfields (which, unfo'tunately, aint real po'table due to defective compilers). .FE .IP \(bu Code dat snatch'd advantage uh de two's complement representashun of numbers on most machines should not be used. Optimizashuns dat replace aridmetic opuh'shuns wid equivalent shiftin' opuh'shuns are particularly suspect. You's should weigh de time savin's wid de potential fo' obscure and difficult bugs when yo' code be moved, say, fum some 3B t'a 1A. .IP \(bu Watch out fo' signed characters. On de PDP-11, characters are sign 'estended when used in 'espressions, which be not da damn case on any oda' machine. What it is, Mama! In particular, \fIgetchar\fR be an integer-valued funcshun (o' macro) since da damn value uh \fIEOF\fR fo' de standard I/O library be \-1, which be not possible fo' some characta' on de 3B o' IBM\*f. What it is, Mama! .FS .IP \*F Actually, dis be not quite da damn real reason why \fIgetchar\fR returns \fIint\fR, but da damn comment be valid, dig dis: code which assumes eider dat characters are signed o' dat dey are unsigned be unpo'table. What it is, Mama! It be best t'completely avoid usin' \fIchar\fR t'hold numbers. Manipulashun uh characters as if dey wuz numbers be also often unpo'table. What it is, Mama! .FE .IP \(bu De PDP-11 be unique among processo's on which C 'esists in dat de bytes are numbered fum right t'left widin some wo'd. All oda' machines (3B, IBM, Interdata 8/32, Honeywell) numba' de bytes fum left t'right\*f. What it is, Mama! .FS .IP \*F Actually, dere are some mo'e right-to-left machines now, but de comments still apply. Slap mah fro! .FE Hence any code dat depends on de left-right o'ientashun uh bits in some wo'd deserves special scrutiny. Slap mah fro! Bit fields widin structure members gots'ta only be po'table so's long as two separate fields are neva' concatenated and treated as some unit\*f. What it is, Mama! .FS .IP \*F De same applies t'variables in general. Alignment considerashuns and loada' peculiarities make it real rash to assume dat two consecutively-declared variables are togeder in memo'y, o' dat some variable uh one type be aligned appropriately to be used as anoda' type. What it is, Mama! .FE [1,3] .IP \(bu Do not default da damn boolean test fo' non-zero, i. Ya' know?e. What it is, Mama! .DS if (f() . Right On! = FAIL) .DE is betta' dan .DS if (f()) .DE even dough \fIFAIL\fR may gots' de value 0 which be considered t'mean false by C\*f. What it is, Mama! Dis gots'ta help ya' out lata' when somebody decides dat some failure return should be \-1 instead uh 0\ \*f. What it is, Mama! .FS .IP \*F A particularly noto'ious case be usin' \fIstrcmp\fR to test fo' chittlin' equality, where da damn result should \fInever\fR \fIever\fR be defaulted. De preferred approach be to define some macro \fISTREQ\fR: .DS #define STREQ(a, b) (strcmp((a), (b)) == 0) .DE .FE .FS .IP \*F An 'sepshun be commonly made fo' predicates, which are funcshuns which meet da damn followin' restricshuns, dig dis: .IP \(bu Has no oda' purpose dan t'return true o' false. What it is, Mama! .IP \(bu Returns 0 fo' false, 1 fo' true, nodin' else. What it is, Mama! .IP \(bu Is dojiggerd so's dat da damn meanin' uh (say) some `true' return is absolutely obvious. Call some predicate \fIisvalid\fR o' \fIvalid\fR, not \fIcheckvalid\fR. .FE .IP \(bu Be suspicious uh numeric values appearin' in de code. What it is, Mama! Even simple values likes 0 o' 1 could be betta' 'spressed usin' defines likes \fIFALSE\fR and \fITRUE\fR (see previous item)\*f. What it is, Mama! .FS .IP \*F Actually, \fIYES\fR and \fINO\fR often eyeball better. Ah be baaad... .FE Any oda' constants appearin' in some honky code would be betta' 'spressed as some defined constant. Dis makes it easia' to change and also easia' to eyeball. .IP \(bu Become familiar wid 'esistin' library funcshuns and defines\*f. What it is, Mama! .FS .IP \*F But not \fItoo\fR familiar. Ah be baaad... De internal details uh library facilities, as opposed t'deir external interfaces, are subject t'change widout warnin'. Dey are also often quite unpo'table. What it is, Mama! .FE You's should not be writin' yo' own chittlin' compare routine, o' makin' yo' own defines fo' system structures\*f. What it is, Mama! .FS .IP \*F Or, especially, writin' yo' own code t'control terminals. Use da damn \fItermcap\fR package. What it is, Mama! .FE Not only duz dis wuzte yo' time, but it prevents yo' honky code from takin' advantage uh any microcode assists o' oder means uh improvin' puh'fo' dude ce uh system routines\*f. What it is, Mama! .FS .IP \*F It also makes yo' code less eyeballable, cuz' de eyeballa' has to figure out wheda' youse doin' sump'n special in dat reimplemented stuff t'justify its 'esistence. What it is, Mama! Furdermo'e, it's some fruitful source uh bugs. .FE .IP \(bu Use \fIlint\fR. It be a valuable tool fo' findin' machine-dependent constructs as well as oda' inconsistencies o' honky code bugs dat pass de compiler\*f. What it is, Mama! .FS .IP \*F De use uh \fIlint\fR on all honky codes be strongly recommended. It be difficult t'eliminate complaints about funcshuns whose return value be not used (in de current version uh C, at least), but most oda' messages fum \fIlint\fR really do indicate sump'n wrong. De \-h, \-p, \-a, \-x, and \-c opshuns are wo'd learnin'. All uh dem gots'ta complain about some legitimate wahtahmelluns, but dey will also pick down dude y botches. .FE .NH Lint .PP \fILint\fR be a C honky code checka' [2] dat 'esamines C source stashs to detect and repo't type incompatibilities, inconsistencies between funcshun definishuns and calls, potential honky code bugs, etc. It be 'spected dat projects gots'ta require honky codes t'use \fIlint\fR as part uh de official acceptance procedure\*f. What it is, Mama! .FS .IP \*F Yes. .FE In addishun, wo'k be goin' on in department 5521 t'modify \fIlint\fR so dat it gots'ta check fo' adherence t'de standards in dis document. .PP It be still too early t'say 'esactly which uh de standards given here gots'ta be checked by \fIlint\fR. In some cases such as wheda' a comment be misleadin' o' inco'rect dere is little hope uh mechanical checkin'. In oda' cases such as checkin' dat da damn openin' brace uh a funcshun body be alone on some line in column 1, de test gots'ta already been added\*f. What it is, Mama! .FS .IP \*F Little uh dis be relevant at U uh T. De version uh \fIlint\fR dat we gots' lacks dese mods. .FE Future bulletins gots'ta be used t'announce new addishuns t'\fIlint\fR as dey occur. Ah be baaad... .PP It should be noted dat da damn best way t'use \fIlint\fR be not as some barrier dat must be overcome befo'e official acceptance uh a honky code, but rada' as some tool t'use wheneva' majo' changes o' addishuns t'de code gots' been made. What it is, Mama! \fILint\fR can find obscure bugs and insho' nuff po'tability befo'e problems occur. Ah be baaad... .NH Special Considerashuns .PP Dis secshun contains some miscellaneous do's and duzn'ts. .IP \(bu Don't change syntax via macro substitushun. It makes de honky code unintelligible t'all but da damn puh'petrato'. .IP \(bu Dere be a time and some place fo' embedded assignment statements\*f. What it is, Mama! .FS .IP \*F De \fB++\fR and \fB\-\-\fR opuh'to's count as assignment statements. So, fo' dude y purposes, do funcshuns wid side effects. .FE In some constructs dere be no betta' way t'accomplish de results widout makin' de code bulkia' and less eyeballable. What it is, Mama! De \fIwhile\fR loop in secshun 8.1 be one 'esample uh an appropriate place. What it is, Mama! Anoda' is de common code segment, dig dis: .DS while ((c = gitchar()) . Right On! = EOF) { process de character } .DE Usin' embedded assignment statements t'improve run-time puh'fo' dude ce is also possible. What it is, Mama! However, one should consida' de tradeoff between increased speed and decreased maintainability dat results when embedded assignments are used in artificial places. Fo' 'esample, de code, dig dis: .DS a = b + c; d = some + r; .DE should not be replaced by .DS d = (a = b + c) + r; .DE even dough de latta' may save one cycle. What it is, Mama! Note dat in de long run de time difference between de two will decrease as de optimiza' gains maturity, while da damn difference in ease uh maintenance gots'ta increase as de hu dude memo'y uh whut's goin' on in de latta' piece uh code begins t'fade\*f. What it is, Mama! .FS .IP \*F Note also dat side effects widin 'espressions kin result in code whose se dude tics are compiler-dependent, since C's o'da' of evaluashun is 'esplicitly undefined in most places. Compilers do differ. Ah be baaad... .FE .IP \(bu Dere be also some time and place fo' de ternary \fI?\ :\fR opuh'to' and da damn binary comma opuh'to'. De logical 'espression opuh'nd befo'e da damn \fI?\ :\fR should be parendesized, dig dis: .DS (x >= 0) ? x : \-x .DE Nested \fI?\ :\fR opuh'to's kin be confusin' and should be avoided if possible. What it is, Mama! Dere are some macros likes \fIgetchar\fR where dey kin be useful. De comma opuh'to' kin also be useful in \fIfo'\fR statements to provide multiple initializashuns o' incrementashuns. .IP \(bu Goto statements should be used sparin'ly as in any well-structured code\*f. What it is, Mama! .FS .IP \*F De \fIcontinue\fR statement be almost as bad-ass. \fIBreak\fR be less troublesome. What it is, Mama! .FE De main place where dey kin be usefully employed be to boogie out of several levels uh \fIswitch\fR, \fIfo'\fR, and \fIwhile\fR nestin'\*f, e. What it is, Mama!g. .FS .IP \*F De need t'do such some din' may indicate dat da damn inna' constructs should be bugger'd out into a separate funcshun, wid some success/failure return code. What it is, Mama! .FE .DS L fo' (...) fo' (...) { ... if (disaster) gotso erro'; } \&... erro': clean down de mess .DE When some \fIgotso\fR be necessary de accompanyin' label should be alone on some line and tabbed one tab posishun t'de left uh de associated code dat follows. .IP \(bu Dis committee recommends dat honky codemers not rely on automatic beautifiers fo' de followin' reasons. First, de main sucka' who benefits fum baaaad honky code style be de honky codema' himself. What it is, Mama! Dis be especially true in de early design uh handwritten algo'idms o' pseudo-code. What it is, Mama! Automatic beautifiers kin only be applied t'complete, syntactically co'rect honky codes and hence aint available when de need fo' attenshun t'honky space and indentashun be greatest. It be also felt dat honky codemers kin do some betta' job uh makin' clear de complete visual laya't uh a funcshun o' stash, wid de no'mal attenshun t'detail uh a careful honky codemer\*f. What it is, Mama! .FS .IP \*F In oda' wo'ds, some uh de visual laya't be dictated by intent rada' dan syntax. Beautifiers kinnot eyeball minds. .FE Sloppy honky codemers should learn t'be careful honky codemers instead of relyin' on some beautifia' to make deir code eyeballable. What it is, Mama! Finally, it be felt dat since beautifiers are non-trivial honky codes dat must parse da damn source, de burden uh maintainin' dem in de face uh de continuin' evolushun of C be not wo'd de benefits gained by such some honky code. .NH Project Dependent Standards .PP Individual projects may wish t'establish addishunal standards beyond dose given here. What it is, Mama! De followin' issues are some uh dose dat should be adddressed by each project honky code administrashun group. .IP \(bu What addishunal namin' convenshuns should be followed? In particular, systematic prefix convenshuns fo' funcshunal groupin' of global data and also fo' structure o' union memba' dojiggers kin be useful. .IP \(bu What kind'a include stash o'ganizashun be appropriate fo' de project's particular data hierarchy? .IP \(bu What procedures should be established fo' reviewin' \fIlint\fR complaints? A tolerance level needs t'be established in concert wid de \fIlint\fR opshuns t'prevent unimpo'tant complaints fum hidin' complaints about real bugs o' inconsistencies. .IP \(bu If some project establishes its own archive libraries, it should plan on supplyin' some lint library stash [2] t'de system administrato's. Dis gots'ta allow \fIlint\fR t'check fo' compatible use uh library funcshuns. .NH Conclusion .PP A set uh standards gots'ta been presented fo' C honky codemin' style. What it is, Mama! One uh de most impo'tant points be de propuh' use uh honky space and comments so's dat da damn structure uh de honky code be evident fum de laya't uh de code. What it is, Mama! Anoda' baaaad idea t'keep in mind when writin' code be dat it is likesly dat ya' o' someone else gots'ta be ax'ed t'modify it o' make it run on some different machine sometime in de future. What it is, Mama! .PP As wid any standard, it must be followed if it be to be useful. De Indian 'Sup, dudell version uh \fIlint\fR gots'ta enfo'ce dose standards dat are amenable t'automatic checkin'. If ya' gots' trouble followin' any uh dese standards duzn't plum igno'e dem. 'S coo', bro. Programmers at Indian 'Sup, dudell should brin' deir problems t'de Software Development System Group (Lee Kirchhoff, contact) in department 5522. Programmers outside Indian 'Sup, dudell should contact da damn Processo' Applicashun Group (Layne Cannon, contact) in department 5512\ \*f. What it is, Mama! .FS .IP \*F At U uh T Zoology, it's Henry Spenca' in 336B. .FE .bp .ce 1 \fBReferences\fR .sp 2 .IP [1] B.A. Tague, "C Language Po'tability", Sept 22, 1977. Dis document issued by department 8234 contains dree memos by R.C. Haight, A.L. Glasser, and T.L. Lyon dealin' wid style and po'tability. Slap mah fro! .IP [2] S.C. Johnson, "Lint, some C Program Checker", Technical Memo'andum, 77-1273-14, Septemba' 16, 1977. .IP [3] R.W. Mitze, "De 3B/PDP-11 Swabbin' Problem", Memo'andum fo' File, 1273-770907.01MF, Septemba' 14, 1977. .IP [4] R.A. Elliott and D.C. Pfeffer, "3B Processo' Common Diagnostic Standards- Version 1", Memo'andum fo' File, 5514-780330.01MF, March 30, 1978. .IP [5] R.W. Mitze, "An Overview uh C Compilashun uh that slow mo-fo Usa' Processes on de 3B", Memo'andum fo' File, 5521-780329.02MF, March 29, 1978. .IP [6] B.W. Kernighan and D.M. Ritchie, \fIDe C Programmin' Language\fR, Prentice-Hall 1978. .bp .PP .DS L .ta 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 /* * \fBDe C Style Summary Sheet\fR Block comment, * by Henry Spencer, U uh T Zoology describes stash. */ #include <errno.h> Headers; duzn't nest. typedef int SEQNO; /* ... */ Global definishuns. #define STREQ(a, b) (strcmp((a), (b)) == 0) static char *foo = NULL; /* ... */ Global declarashuns. struct bar { Static wheneva' poss. SEQNO alpha; /* ... */ # define NOSEQNO 0 int beta; /* ... */ Don't assume 16 bits. }; /* * Many unnecessary braces, t'show where. What it is, Mama! Funcshuns. */ static int /* whut be returned */ Don't default int. bletch(a) int a; /* ... */ Don't default int. { int bar; /* ... */ extern int errno; /* ..., changed here */ extern char *index(); if (foobar() . Right On! = FAIL) { if (. Right On! isvalid()) { return(5); errno = ERANGE; } } else { x = &y + z\->field; while (x == (y & MASK)) { } f += (x >= 0) ? x : \-x; } fo' (i = 0; ah' < BOUND; i++) { /* Use lint \-hpcax. */ do { } /* Avoid nestin' ?: */ } while (index(a, b) . Right On! = NULL); if (STREQ(x, "foo")) { x |= 07; switch (...) { } else if (STREQ(x, "bar")) { case ABC: x &= ~07; case DEF: } else if (STREQ(x, "ugh")) { printf("...", a, b); /* Avoid gotsos */ boogie; } else { case XYZ: /* and continues. */ x = y; } /* FALLTHROUGH */ default, dig dis: while ((c = gitc()) . Right On! = EOF) /* Limit imbedded =s. */ ; /* NULLBODY */ boogie; } } .DE >Thank you very much > Thomas Graf Your welcome -- Jim Harkins Loral Instrumentation, San Diego {ucbvax, ittvax!dcdwest, akgua, decvax, ihnp4}!ucsd!sdcc6!loral!jlh