home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!usc!news!netlabs!lwall
- From: lwall@netlabs.com (Larry Wall)
- Newsgroups: comp.lang.perl
- Subject: Re: Perl language formatting conventions?
- Message-ID: <1992Aug27.042932.3143@netlabs.com>
- Date: 27 Aug 92 04:29:32 GMT
- References: <1992Aug25.152315.20630@news.eng.convex.com> <BtJux7.CEp@news.cso.uiuc.edu> <1992Aug25.224912.1775@news.eng.convex.com>
- Sender: news@netlabs.com
- Distribution: comp
- Organization: NetLabs, Inc.
- Lines: 214
- Nntp-Posting-Host: scalpel.netlabs.com
-
- In article <1992Aug25.224912.1775@news.eng.convex.com> tchrist@convex.COM (Tom Christiansen) writes:
- : Here's the Berkeley style guide for comparison. I don't personally
- : use all of them (i.e. I use 4-space indents and test pointers with
- : a raw "if (p)') but surprisgnly, I find that many I do use even
- : though I had never read this guide.
-
- I also use 4-space indent, in case you hadn't noticed. :-)
-
- I'm gonna comment on some of these C thingies, so if you're here to read
- about Perl formatting you can type "n" now.
-
- : /*
- : * Macros are capitalized, parenthesized, and should avoid side-effects.
- : * If they are an inline expansion of a function, the function is defined
- : * all in lowercase, the macro has the same name all in uppercase. If the
- : * macro needs more than a single line, use braces. Put a space before
- : * the backslashes.
- : */
- : #define MACRO(x, y) { \
- : variable = (x) + (y); \
- : line two; \
- : }
-
- I'd line up the backslashes--it's an awful lot easier to see when you've
- left one out.
-
- : /* Enum types are capitalized. */
- : enum enumtype { ONE, TWO } et;
-
- Those are enum *values*, not types.
-
- : /*
- : * When declaring variables in structures, declare them sorted by use, then
- : * by size, and then by alphabetical order. The first category normally
- : * doesn't apply, but there are exceptions. Each one gets its own line.
- : * Put a tab after the first word, i.e. use "int^Ix;" and "struct^Ifoo *x;".
- : *
- : * Major structures should be declared at the top of the file they are
- : * used in, or in separate header files, if they are used in multiple
- : * source files. Use of the structures should be by separate declarations
- : * and should be "extern" if they are declared in a header file.
- : */
- : struct foo {
- : struct foo *next; /* List of active foo */
- : struct mumble amumble; /* Comment for mumble */
- : int bar;
- : };
- : struct foo *foohead; /* Head of global foo list */
-
- What they didn't say was that you sort the variables in structures
- by *decreasing* size. This makes for the most compact representation
- without the compiler cheating on the semantics of C.
-
- I also think it's silly to put the tab between "struct" and the type
- name. I'm of two minds as to where to put the tab on pointers to
- structures. Sometimes I put
-
- struct foo *next;
-
- and sometimes
-
- struct foo* next;
-
- depending on how heavily I'm into denial over C's type syntax. I've
- been doing more of the latter lately.
-
- : while ((ch = getopt(argc, argv, "abn")) != EOF)
- : switch (ch) { /* Indent the switch. */
- : case 'a': /* Don't indent the case. */
- : aflag = 1;
- : /* FALLTHROUGH */
- : case 'b':
- : bflag = 1;
- : break;
- : case 'n':
- : num = strtol(optarg, &ep, 10);
- : if (num <= 0 || *ep)
- : err("illegal number -- %s", optarg);
- : break;
- : case '?':
- : default:
- : usage();
- : }
-
- This is evil. Any dangled statement longer than one line should be
- enclosed in braces. One of the reasons I require braces in Perl...
-
- : /*
- : * Space after keywords (while, for, return, switch). No braces are
-
- Yes. I don't want my keywords looking like functions, and vice versa.
-
- : * used for single statement block.
- : *
- : * Forever loops are done with for's, not while's.
- : */
- : for (;;)
- : stmt;
-
- Yes, I find the (;;) visually distinctive for a distinctive idea, and
- C needs all the visual distinctiveness it can muster.
-
- : /*
- : * Try to put shorter part first. The closing and opening braces
- : * go on the same line as the else.
- : */
- : if (test)
- : stmt;
- : else if (bar) {
- : stmt;
- : stmt;
- : } else
- : stmt;
-
- I prefer my else's to line up, but that's just taste. Whether to put
- the shorter part first depends on how easy it is to express the conditional
- in an understandable way. Sometimes I go so far as to change the name
- of a Boolean variable so that I can put the right branch first without
- extra !'s. The real trick is to find the opposite name for the Boolean
- variable without just putting "no" on the front of it... :-)
-
- : /* No space after function names. */
- : if (error = function(a1, a2))
- : exit(error);
-
- Yes. I don't want my keywords looking like functions, and vice versa.
- The parens of a function are an intrinsic part of the function call in C.
- Pretending that a function name is a unary operator prefixing an ordinary
- parenthesized list is bogus to me.
-
- : /*
- : * Unary operators do not require spaces, binary operators do.
- : * Try not to use too many parenthesis unless the statement is
- : * really confusing without them.
- : */
- : a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
- : k = l & FLAGS;
-
- Hmm, sometimes you just need to break up an expression and indent it
- reasonably. Sometimes you can omit the spaces on a binary operator to
- imply precedence:
-
- a + b*c + d;
-
- : /*
- : * Exits should be 0 on success, and 1 on failure. Don't denote
- : * all the possible exit points, using the integers 1 through 300.
- : */
- : exit(0); /* Avoid obvious comments such as "Exit 0 on success." */
-
- Obviously, you have to get along with Unix here, but for return values
- I prefer "success" to be associated with "truth". You can pass the
- (presumably infrequent) error information by some other mechanism when
- necessary, and then you won't be tempted to shoehorn too much meaning
- into a simple-minded integer.
-
- : /*
- : * If a function type is declared, it should be on a line
- : * by itself preceeding the function.
- : */
- : static char *
- : function(a1, a2, a3, a4)
-
- Yes, and notice that they're doing a line break where earlier I said
- I liked doing a tab--after the *. But of course, the reason is
- rather different here. We want to be able to search using /^function.
-
- : int a1, a2, a4; /* Declare ints too. */
-
- I'd put these on separate lines.
-
- : /*
- : * Casts and sizeof's are not followed by a space. NULL is any
- : * pointer type, and doesn't need to be cast, so use NULL instead
- : * of (struct foo *)0 or (struct foo *)NULL.
-
- This can break when passing arguments to functions. I prefer to use
- typed NULLish thingies for documentation purposes consistently, and
- then I don't forget to cast them when I use them as function
- arguements. So I end up with Nullch, Nullfp, etc, or in the general
- case, Null(FOO*).
-
- : * Also, test pointers against NULL, i.e. use:
- : *
- : * (p = f()) == NULL
- : * not:
- : * !(p = f())
-
- NO! This is a throw-back to Pascal, in which conditionals require
- Boolean values and only Boolean values. C blesses the notion that many
- types can be used as Boolean values. C++ carries this even further,
- and essentially provides that any user-defined type for which it makes
- sense can be set up to be used as a Boolean value.
-
- : *
- : * Routines returning void * should not have their return values cast
- : * to any pointer type.
- : */
- : if ((four = malloc(sizeof(struct foo))) == NULL)
- : return (NULL);
-
- That's contrary to usual industry practice. Fortunately the necessity
- for it goes away in C++.
-
- : if ((six = (int *)overflow()) == NULL)
- : return (NULL);
- : return (eight);
-
- Of what earthly good are the parens around a return value, other than to
- make Yet Another Keyword look like a function?
-
- Well, enough of that. Back to your regularly scheduled programming.
-
- Larry
-