aboutsummaryrefslogtreecommitdiff
path: root/src/CODESTYLE
blob: 56be3ea54a9f2874b67b081fdb2182a266ccc0f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
AHFinderDirect Code Style
=========================
$Header: /usr/local/svn/cvs-repositories/numrelcvs/AEIThorns/AHFinderDirect/src/CODESTYLE,v 1.2 2003-05-06 15:43:54 jthorn Exp $

This file documents some general programming conventions used in this
thorn.

File Naming
===========
*.c, *.h	C code, headers		*.c, *.h
*.cc, *.hh	C++ code, headers	*.cc, *.hh

At least as of version 7, Maple doesn't have a usable preprocessor,
so I've written my own (src/mpp).

*.maple		Maple code (input to my Maple preprocessor)
*.minc		Maple headers to be @included by my Maple preprocessor
*.mm		Maple code (output from my Maple preprocessr)

None of my header files ever #includes another file, so in theory there's
no problem with multiple inclusion.  However, see "C++ Templates" below
for some ugly compiler problems with this...


Configuration
=============

Only a few options are configured at compile-time; these use #defines
in src/include/config.h.


Code Layout/Indentation
========================

Most comments are C++-style //-to-end-of-line comments.  In C files,
or in header files which have to be C-compatible, I use C-style
/* comments */.

I like to make the two branches of an if-else statement look symmetrical:
so I use
  #define then   /* empty */
with usage as shown below.

A lot of the code uses the generic floating-point data type
  typedef CCTK_REAL fp;

Almost (but not quite) all the code fits into 80 columns.

The indentation style is typified by the following examples.  Roughly
speaking, indentation depth reflects execution frequency.  Normal
indentation is 1 tab stop = 8 spaces.  Sometimes a block of code is
"outdented" back towards the left margin if it's too deeply indented
to fit easily in an 80-column window.

... surrounding code
if (condition)
   then ... if-condition-true code
   else ... if-condition-false code

... surrounding code
	while (condition)
	{
	... body of while loop
	}


All switch statements should have a  default:  case (which often just
does an  error_exit()).

... surrounding code
switch	(expression)
	{
case 42:
	... code for this case
	break;
case 69:
	... code for this case
	break;
case 105:
	... code for this case
	break;
default:
	... code for this case
	break;
	}

//
// block comment describing function
//
int foo(fp x, int bar, int baz)
{
... body of function
}

All code should be fully type-secure: there is no aliasing of different
data types.  const qualifiers are used whereever possible, and all code
should be const-correct.

Most casts are new-style  const_cast<...>(...)  or  static_cast<...>(...) .
There are no  reinterpret_cast<...>(...)  or  dynamic_cast<...>(...) .
There are no C-style casts  (type) value .  The only function-style
casts   type(value)  are to cast numeric datatypes to int/double for
printf()-style printing, eg
  void print_x(fp x)
  {
  printf("x=%g\n", double(x));    // we don't know if fp is C float or double
  }


Error Handling
==============

For historical reasons, the code uses two slightly different mechanisms
for "print an error message and abort the Cactus run" error handling:
* Lower-level code (in src/{jtutil,patch,gr,elliptic}/) uses error_exit()
  (defined in src/include/stdc.h):
	if (user input was very bad)
	   then error_exit(ERROR_EXIT,
"***** function_name(): user input was really bad\n"
"                       printf(3)-style string and following arguments\n"
"                       to describe what went wrong"
			   ,
			   foo, var, double(baz));		/*NOTREACHED*/
  Here the first argument is ERROR_EXIT for "bad user input" errors,
  or PANIC_EXIT for "this should never happen" failure of internal
  consistency checks.  For this thorn, error_exit() is implemented as
  a call to...
* Higher-level code (in src/{driver,elliptic,gr}) uses the standard
  Cactus CCTK_VWarn(), generally giving FATAL_ERROR (defined in
  src/include/config.h) as the warning level.


C++ Classes and Libraries
=========================

All the main data structures are C++ classes, but there are also plenty
of C-style structs.  struct foo  is for "dumb data", and has at most
contructors.  class foo  is for full-fledged C++ classes; these have
no public data members.  C++ class data members have names with a
trailing underscore; no other identifiers in this thorn have such names.

Most "large" classes are non-copyable and non-assignable.  Right now
I write this explicitly in each class; once compilers improve a bit more
and boost becomes more widely deployed it would be cleaner to convert this
to inheriting from boost::noncopyable.

In the same genre, once compilers imprive a *lot* more :), most/all
of the raw new[]-array references should probably be converted to
boost::array, and my jtutil::array[1234]d<> classes should be converted
to boost::multi_array.


C++ Templates
=============

I use C++ templates, but not for anything fancy, just simple containers.
I instantiate all templates explicitly.

Some C++ compilers offer "automatic" template instantiation.  In practice
this often causes compilation to fail when the compiler can't find .cc
files in other directories.  So, I highly recommend turning *off* all
automatic template instantiation "features".

When using the DEC/Compaq/HP/whatever-their-corporate-name-is-this-week
C++ compiler (version 6.3.6.8) under Alpha Linux, even with automatic
template instiation disabled, the compiler *still* seems to include some
header files multiple times.  To avoid duplicate-definition errors caused
by this, I have protected all the header files in the subdirectories
   include/
   jtutil/
   elliptic/
against multiple inclusion with the standard #ifndef trick.


Miscellaneous
=============

All I/O is done using C stdio (printf() and friends); the C++ iostreams
system isn't used.

Some Cactus parameter names, and some C++ enumeration and function 
names, contain the substring "__" (two consecutive underscores).
According to the C++ standard, such names are reserved to the [compiler]
implementation.  In practice, so far I haven't had any problems...