[comp.lang.c] Scientific C style choices

pekka@majestix.liu.se (Pekka Akselin [The Mad Midnight Hacker]) (01/13/89)

In article <11091@ulysses.homer.nj.att.com> ggs@ulysses.homer.nj.att.com (Griff Smith) writes:
>[...]
>if (   mumble
>    && mumble
>    && mumble
>    && mumble )
>{
>	mumble;
>	mumble;
>}

I don't like this, though I AM a extremely 'visual' person.



I'd like it this way: (I apologize for my bad english, though I hope you'll
understand my words. More commments (by me) on the style just after the "file")

================ file begins ================
				<---- Line feed, for "air" in the file.
/*
 * This-file comment.		<---- Capital letter on first word and
 * Copyright info.			a period after the sentence.
 */					I. e. normal writing rules.

#include <stdio.h>
#include <ctype.h>		<---- Include's grouped together if possible.

#define up22(x)	sqrt(x)		<---- Same for define's.
#define BAD	-1

				<---- 3 line feeds.

/*
 * Externs declared here, if any.
 */

char	a_ch;			<---- Variables declared in alphbetical
char	b_ch;				order. I. e. char's are declared
					before int's and so on.
int	one1;
int	power;			/* Short comments like this ... */

/*
 * ... especially when commenting variable declarations.
 */

/*
 * Longer comments like this.
 *
 * Variables not sorted on struct or union tag's!
 */
struct weather	age;
struct old }

	int	because;
	int	why;
{ test_pattern[1] = }

	{ 2,	3}
{
union jack	labor_union:

				<---- 3 line feeds.

int	main(argc, argv)
int	argc;
char	*argv[]; {		<---- Consistent with (e.g.) if-statements.

	/*
	 * Register decl's first! But not before externs.
	 */
	register struct old	something;

	char	abc;

	int	one_two_three;

				<---- 3 line feeds.

	switch (ok) {
	case 1:			<---- Only the case tag here.
		some_proc(54);
		break;
	default:
		exit(0);
		break;		<---- I usually put a break here too.
	}

	/*
	 * All cond_expr on the same line (there are laserwriters that
	 * prints in landscape mode 8-). Comments that belongs to a part
	 * of the code is connected to it through not having line feeds
	 * after the comment.
	 */
	if (mumble && mumble && mumble && mumble) {
		code;
		code;
	} else {		<---- These on same row! No exeption!
		some_proc(3);
		if (garp && toe) {
			puts("Hello world!\n");
		}
	}			<---- Gives some space before next block.
	(void)putchar('\n');
				<---- Line feeds inserted for readability.
	exit(0);

	/*NOTREACHED*/
} /* main */

				<---- Again 3 line feeds.

unsigned int	some_proc(t)	<---- TAB's only before varible-names.
register int	t; {		<---- SPACE's otherwise.

	do {
		t++;
		t += t * 65;
		t = (unsigned char)0xff;

	} while (cond_expr1 || cond_expr2);

	return (unsigned int)t;
{ /* some_proc */
================ file ends ================

Some comments on my style:

The '}' `pulls' bak the code indentation one TAB.
Thats why I have it `under' the beginning of the statement that caused
the indentation. I always use the '{}' even if the (e.g.) if-body is
a single statement. If you do this then you always can see directly where
the else's belongs.

I have a comment after the '}' that ends a function 'cause when you have
long functions you can then see which function you edit when you are at the 
end of it (especially when you are in the progress of coding the function -
- I(!) have a short memory 8-).

The "return"-statement does NOT have paren's around it's "argument" 'cause
it's NOT a function call! It's merely a compiler directive, saying "return
to the calling function". It is NOT logical having it look like a function
call!

Cast's is `connected' to it's `argument' through not having a SPACE between
the cast and argument. It is a operator on the argument in the same manner
as the '++' or '--' operators are. Many of you code like "ptr++" or "--i"
and no one argues that. It is natural.

I always put only one statement on a row.

The case tags functions like '{}', indenting and unindenting the code.



Well that's some of my coding rules, and I think it gives readable code.
And it is my hope that you will adopt this style of coding 8-)

Have a nice day (or night or whatever is appropriate)
Thanks for having your attention for a while.

-- 
	/pekka			  
_______________________________________________________________________________
pak@ida.liu.se			  [...The Mad Midnight Hacker Strikes Again...]
Pekka Akselin, Univ. of Linkoping, Sweden  (The Land Of The Midnight Hacker 8-)

logan@vsedev.VSE.COM (James Logan III) (01/24/89)

In article <1136@majestix.liu.se> pekka@majestix.liu.se
(Pekka Akselin [The Mad Midnight Hacker]) writes:
# ================ file begins ================
# 				<---- Line feed, for "air" in the file.
# /*
#  * This-file comment.		<---- Capital letter on first word and
#  * Copyright info.			a period after the sentence.
#  */					I. e. normal writing rules.
# 
# #include <stdio.h>
# #include <ctype.h>		<---- Include's grouped together if possible.
# 
# #define up22(x)	sqrt(x)		<---- Same for define's.
# #define BAD	-1
# 
# 				<---- 3 line feeds.
# 
# /*
#  * Externs declared here, if any.
#  */

Up to this point you have exactly the same style I have developed!  I am
very surprised to see this!

# char	a_ch;			<---- Variables declared in alphbetical
# char	b_ch;				order. I. e. char's are declared
# 					before int's and so on.
# int	one1;
# int	power;			/* Short comments like this ... */

I usually declare variables like this:

char
	a_ch,		/* One comment for each variable to	*/
	b_ch,		/* describe the intent.			*/
	c_ch;		/* All end-comment tokens line up. -->	*/

int
	a_int,		/* More comments would normally go	*/
	b_int,		/* next to these integers.		*/
	c_int;

struct already_defined
	first,		/* More comments.  Notice how the	*/
	second,		/* "struct ..." does not bump the	*/
	third;		/* variable(s) over one more tabstop.	*/

# struct old }
# 
# 	int	because;
# 	int	why;
# { test_pattern[1] = }
# 
# 	{ 2,	3}
# {

I use almost the same style here, only with the braces facing the
right way and with the array declared with the right number of
elements! :-) 

struct old {
	int	because;	/* More descriptive text.		*/
	int	why;		/* And still more.			*/
} test_pattern[] = {
	{2,	3	},	/* I usually put a tab between		*/
	{4,	5	},	/* The values so the numbers		*/
	{500,	1000	}	/* line up and are easy to read.	*/
}

#
# 				<---- 3 line feeds.
# 

I also put linefeeds between every function.  Actually, I use 4.  I also
put a long descriptive comment above the function definition like this:

/*
 * some_func()
 *
 * Do something that is a complete waste of time and return.
 */

# int	main(argc, argv)
# int	argc;
# char	*argv[]; {		<---- Consistent with (e.g.) if-statements.

I would declare this as:

int	main(argc, argv)
	int	argc;
	char	**argv;
{
}

The parameters are indented just like in an outline -- more
details are indented:  

1. Statement
	1.1. Details about the statement
	1.2. More details

2. Some other Statement

3. Et cetera

Note that the ONLY time I have an open brace underneath anything is
in a function definition.  It is not consistent with "if" statements,
but, to me, it looks a lot better.

# 	switch (ok) {
# 	case 1:			<---- Only the case tag here.
# 		some_proc(54);
# 		break;
# 	default:
# 		exit(0);
# 		break;		<---- I usually put a break here too.
# 	}

Exactly.  Well, I might not use the last break...

# 	/*
# 	 * All cond_expr on the same line (there are laserwriters that
# 	 * prints in landscape mode 8-). Comments that belongs to a part
# 	 * of the code is connected to it through not having line feeds
# 	 * after the comment.
# 	 */
# 	if (mumble && mumble && mumble && mumble) {
# 		code;
# 		code;
# 	} else {		<---- These on same row! No exeption!

Exactly!  I think the

	if (expr) {
		f();
	} else {
		f();
	}

is much more readable than

	if (expr) {
		f();
	}
	else {
		f();
	}

# 		some_proc(3);
# 		if (garp && toe) {
# 			puts("Hello world!\n");
# 		}
# 	}			<---- Gives some space before next block.
# 	(void)putchar('\n');
# 				<---- Line feeds inserted for readability.
# 	exit(0);
# 
# 	/*NOTREACHED*/
# } /* main */

I have never put a comment next to a closing brace.  I don't see
the need since I only have to look up to find the function
definition that it belongs to.  If the function is too long to do
that I break the code out into more functions.  

# Some comments on my style:
# 
# The "return"-statement does NOT have paren's around it's "argument" 'cause
# it's NOT a function call! It's merely a compiler directive, saying "return
# to the calling function". It is NOT logical having it look like a function
# call!

Right.

# Cast's is `connected' to it's `argument' through not having a SPACE between
# the cast and argument. It is a operator on the argument in the same manner
# as the '++' or '--' operators are. Many of you code like "ptr++" or "--i"
# and no one argues that. It is natural.

Absolutely!

In addition to this style description I would like to add a few
conventions of my own.  

1. All global variables have the first letter capitalized to
avoid collisions with local variables.  

2. main() is declared at the bottom of the file so that I do not
have to declare any functions before they are defined.  If they
are declared in a different module I always use:

extern char
	*mystrlen(),	/* I list what files contain these	*/
	*mystrcpy();	/* functions here.			*/

extern void
	fatal(),
	update_clock();

(I usually put these in a header file in addition to "extern"
declarations for all global variables when I'm working on a large
project.) 


			-Jim

-- 
Jim Logan                           logan@vsedev.vse.com
VSE Software Development Lab        uucp:  ..!uunet!vsedev!logan
(703) 418-0002                      inet:  logan%vsedev.vse.com@uunet.uu.net