1 marek 1.1 <html>
2
3 <head>
4 <meta http-equiv="Content-Language" content="en-us">
5 <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
6 <title>PEP 221 - Pegasus Coding Conventions</title>
7 <link rel="stylesheet" href="http://www.opengroup.org/stylesheets/info1+margins.css">
8 </head>
9
10 <body>
11
12 <hr>
13
14 <p align="center"><b><font size="4">Pegasus Enhancement Proposal (PEP)</font></b></p>
15 <p><b>PEP #:</b> 221</p>
16 <p><b>Title:</b> Pegasus Coding Conventions</p>
17 <p><b>Status:</b> Approved</p>
18 <p><b>Version History:</b></p>
19 <table border="1" cellspacing="1" bordercolordark="#666666"
20 bordercolorlight="#CCCCCC" width=100%
21 style='font-size=10.0pt;font-family:Arial'>
22 marek 1.1 <tr>
23 <th bgcolor="#CAE6CA">Version</th>
24 <th bgcolor="#CAE6CA">Date</th>
25 <th bgcolor="#CAE6CA">Author</th>
26 <th bgcolor="#CAE6CA">Change Description</th>
27 </tr>
28 <tr>
29 <td align="center">1.0</td>
30 <td align="center">23 February 2005</td>
31 <td align="center">Roger Kumpf</td>
32 <td>Initial submittal, based on documents in pegasus/doc directory in CVS
33 (conventions.txt, portability.txt, CodeReviewNotes.txt, and DOCREMARKS).
34 </td>
35 </tr>
36 <tr>
37 <td align="center">1.1</td>
38 <td align="center">1 March 2005</td>
39 <td align="center">Roger Kumpf</td>
40 <td>Updated based on 3/1/05 architecture review comments.<br>
41 <em>Approved version (Ballot 95).</em></td>
42 </tr>
43 marek 1.1 <tr>
44 <td align="center">2.0</td>
45 <td align="center">21 March 2005</td>
46 <td align="center">Roger Kumpf</td>
47 <td>Opened up for additional conventions.</td>
48 </tr>
49 <tr>
50 <td align="center">2.1</td>
51 <td align="center">5 August 2005</td>
52 <td align="center">Roger Kumpf</td>
53 <td>Updated based on comments and architecture team discussions.</td>
54 </tr>
55 <tr>
56 <td align="center">2.2</td>
57 <td align="center">21 February 2006</td>
58 <td align="center">Roger Kumpf</td>
59 <td>Updated based on review comments.</td>
60 </tr>
61 <tr>
62 <td align="center">2.3</td>
63 <td align="center">24 February 2006</td>
64 marek 1.1 <td align="center">Roger Kumpf</td>
65 <td>Updated based on review comments and architecture team discussion.</td>
66 </tr>
67 <tr>
68 <td align="center">2.4</td>
69 <td align="center">10 March 2006</td>
70 <td align="center">Roger Kumpf</td>
71 <td>Updated based on ballot comments.<br>
72 <em>Approved version (Ballot 111).</em>
73 </td>
74 </tr>
75 <tr>
76 <td align="center">3.0</td>
77 <td align="center">10 March 2006</td>
78 <td align="center">Roger Kumpf</td>
79 <td>Opened up for additional conventions.</td>
80 </tr>
81 <tr>
82 <td align="center">3.1</td>
83 <td align="center">20 November 2008</td>
84 <td align="center">Roger Kumpf</td>
85 marek 1.1 <td>Updated based on review comments.</td>
86 </tr>
87 <tr>
88 <td align="center">3.2</td>
89 <td align="center">26 November 2008</td>
90 <td align="center">Roger Kumpf</td>
91 <td>Updated based on review comments.</td>
92 </tr>
93 <tr>
94 <td align="center">3.3</td>
95 <td align="center">4 December 2008</td>
96 <td align="center">Roger Kumpf</td>
97 <td>Updated based on review comments.<br>
98 <em>Approved version (Ballot 160).</em>
99 </td>
100 </tr>
101 </table>
102 <p> </p>
103 <hr>
104 <p><b>Abstract:</b> This document formalizes the Pegasus coding conventions.
105 </p>
106 marek 1.1 <hr>
107
108 <h2><font color="#000000">Definition of the Problem</font></h2>
109 <p><The use of inconsistent coding styles is an impediment to
110 effective development and maintenance of Pegasus code. Formalization of
111 Pegasus coding conventions may help to improve code consistency.
112 </p>
113
114 <h2><font color="#000000">Proposed Solution</font></h2>
115 <p>The following items comprise the Pegasus coding conventions.</p>
116
117 <h3>Formatting</h3>
118 <ol>
119 <li>Indent by increments of four spaces. Indent comments
120 equally with the associated code.</li>
121 <li>Do not use tab characters.</li>
122 <li>Lines must not span more than 80 columns.</li>
123 <li>Remove trailing spaces at the end of a line.
124 (Note: This also applies to Makefiles, where trailing spaces may cause
125 unintended whitespace in generated files.)</li>
126 <li>Put opening brace on a line by itself, aligned with control keyword
127 marek 1.1 or method signature.
128 Do this:
129 <pre><code> for (...)
130 {
131 }</code></pre>
132 Not this:
133 <pre><code> for (...) {
134 }</code></pre>
135 Or this:
136 <pre><code> for (...)
137 {
138 }</code></pre>
139 </li>
140 <li>Use braces around the body of a control block (e.g., <code>if</code>,
141 <code>for</code>, or <code>while</code> statement), even if the body
142 contains just a single statement.
143 Do this:
144 <pre><code> for (...)
145 {
146 i++;
147 }</code></pre>
148 marek 1.1 Not this:
149 <pre><code> for (...)
150 i++;</code></pre>
151 </li>
152 <li>Use a new line for <code>else</code> statements rather
153 than placing then on the same line as a preceding '<code>}</code>'.
154 Do this:
155 <pre><code> if (...)
156 {
157 i++;
158 }
159 else
160 {
161 j++;
162 }</code></pre>
163 Not this:
164 <pre><code> if (...)
165 {
166 i++;
167 } else
168 {
169 marek 1.1 j++;
170 }</code></pre>
171 </li>
172 <li>Use normal indenting for parameters in a complex method signature:
173 <pre><code> void MyClass::myMethod(
174 const char* someReallyLongName,
175 const char* someOtherReallyLongName);</code></pre>
176 </li>
177 <li>Use normal indenting for all arguments in a complex function call.
178 Do this:
179 <pre><code> callingMyFunction(
180 arg1,
181 arg2,
182 arg3);</code></pre>
183 Not this:
184 <pre><code> callingMyFunction(arg1,
185 arg2,
186 arg3);</code></pre>
187 Each argument should be placed on a separate line.
188 An exception is made for <code>PEG_TRACE</code> and
189 <code>PEG_TRACE_CSTRING</code> statements, where the first two
190 marek 1.1 arguments should be placed on the opening line:
191 <pre><code> PEG_TRACE((TRC_HTTP, Tracer::LEVEL3,
192 "Connection IP address = %s",
193 (const char*)_ipAddress.getCString()));</code></pre>
194 </li>
195 <li>For an <code>if</code>, <code>while</code>, or <code>for</code>
196 condition that does not fit on a single line, indent peer subconditions
197 according to their level of nesting and indent other continuation lines
198 using normal indenting. Do this:
199 <pre><code> if ((variable1 == variable2) ||
200 ((anotherVariableToConsider ==
201 variable1 + variable2) &&
202 (dayOfWeek == "Tuesday")))</code></pre>
203 Not this:
204 <pre><code> if ((variable1 == variable2) ||
205 ((anotherVariableToConsider ==
206 variable1 + variable2) &&
207 (dayOfWeek == "Tuesday")))</code></pre>
208 </li>
209 <li>For a statement that does not fit on a single line,
210 all continuation lines should be indented once from the first line.
211 marek 1.1 For example:
212 <pre><code> sum = a + b + c +
213 d + e + f +
214 g + h;</code></pre>
215 </li>
216 <li>Do not separate a return type onto its own line. Avoid this:
217 <pre><code> int
218 f()
219 {
220 }</code></pre>
221 </li>
222 <li>Avoid use of "<code>(void)</code>" for an empty parameter list.
223 Use "<code>()</code>" instead.
224 </li>
225 <li>Avoid adding a space between function/method name the opening parenthesis.
226 Do this:
227 <pre><code> void f(int i);
228 f(10);</code></pre>
229 Not this:
230 <pre><code> void f (int i);
231 f (10);</code></pre>
232 marek 1.1 </li>
233 <li>Include a space between a keyword and an opening parenthesis.
234 Do this:
235 <pre><code> if (i > 0)
236 for (i = 0; i < 10; i++)</code></pre>
237 Not this:
238 <pre><code> if(i > 0)
239 for(i = 0; i < 10; i++)</code></pre>
240 </li>
241 <li>Do not add spaces around a condition. Do this:
242 <pre><code> if (cond)
243 while (cond)</code></pre>
244 Not this:
245 <pre><code> if ( cond )
246 while ( cond )</code></pre>
247 </li>
248 <li>Do not add a space between a template name and its type. Do this:
249 <pre><code> Array<Uint8> myArray;</code></pre>
250 Not this:
251 <pre><code> Array <Uint8> myArray;</code></pre>
252 </li>
253 marek 1.1 <li>Avoid aligning variable names in a declaration list. Do this:
254 <pre><code> int x;
255 float y;</code></pre>
256 Not this:
257 <pre><code> int x;
258 float y;</code></pre>
259 </li>
260 <li>Avoid indenting "<code>public:</code>",
261 "<code>protected:</code>", and
262 "<code>private:</code>". Do this:
263 <pre><code> class X
264 {
265 public:
266 int f();
267 ...
268 private:
269 int _g();
270 ...
271 };</code></pre>
272 </li>
273 <li>The '<code>#</code>' indicating a preprocessing directive is placed
274 marek 1.1 at the beginning of a line. Nested preprocessing directives are
275 indented with one space after the '<code>#</code>' for each level of
276 nesting. The <code>#ifndef</code> used for header file include protection
277 is not considered a level of nesting. For example:
278 <pre><code>#ifdef PEGASUS_HAS_SIGNALS
279 # ifdef PEGASUS_OS_TYPE_WINDOWS
280 # include <windows.h>
281 # else
282 # include <unistd.h>
283 # endif
284 #endif</code></pre>
285 </li>
286 <li>In a <code>switch</code> statement, indent the <code>case</code>
287 statement from the <code>switch</code> and indent the case logic from
288 the <code>case</code> statement. For example:
289 <pre><code> switch(n)
290 {
291 case 0:
292 printf("Rock");
293 break;
294 case 1:
295 marek 1.1 printf("Paper");
296 break;
297 case 2:
298 printf("Scissors");
299 break;
300 default:
301 printf("Error");
302 break;
303 }</code></pre>
304 </li>
305 <li>Do not put parentheses around the return value in a
306 <code>return</code> statement.
307 </li>
308 </ol>
309
310 <h3>Naming</h3>
311 <ol>
312 <li>For class/struct names, use mixed case with initial upper case and
313 no underscores: <code>ThisIsAClassName</code>.
314 </li>
315 <li>For public member/variable names, use mixed case with initial lower case
316 marek 1.1 and no underscores: <code>thisIsAMemberName</code>.
317 </li>
318 <li>For public method/function names, use mixed case with initial lower case
319 and no underscores: <code>thisIsAMethodName()</code>.
320 </li>
321 <li>Prepend an underscore to private and protected member and method names:
322 <code>_thisIsAPrivateMemberName</code>,
323 <code>_thisIsAPrivateMethodName()</code>.
324 </li>
325 <li>General constants and macro names should begin with <code>PEGASUS_</code>.
326 </li>
327 <li>Use this format for constant and macro names:
328 <code>PEGASUS_CONSTANT_NAME</code>.
329 </li>
330 <li>Files names should use mixed case with initial upper case and no
331 underscores: <code>ThisIsAFileName.cpp</code>.
332 </li>
333 <li>A file should have the same name (and case) as the class it contains.
334 </li>
335 <li>Environment variables must begin with <code>PEGASUS_</code> and have
336 this form: <code>PEGASUS_ENVIRONMENT_VARIABLE</code>.
337 marek 1.1 This applies to environment variables that control the build and test
338 configuration as well as those (if any) used by Pegasus at run time.
339 </li>
340 <li>Test executable names should begin with 'Test' (to distinguish them
341 from other executables) and should use mixed case with initial upper
342 case and no underscores. The name should clearly indicate the feature
343 being tested. For example: <code>TestFeature1</code>.
344 </li>
345 </ol>
346
347 <h3>Style</h3>
348 <ol>
349 <li>In a header file, use angle brackets (with a fully qualified path)
350 rather than quotes when including a file. Do this:
351 <pre><code> #include <Pegasus/Common/Array.h></code></pre>
352 Not this:
353 <pre><code> #include "Array.h"</code></pre>
354 </li>
355 <li>Use "<code>0</code>" rather than "<code>NULL</code>"
356 as a null pointer value.
357 </li>
358 marek 1.1 <li>Avoid <code>throw()</code> declarations. These may be used
359 only when a method must not (and will not) throw any exception not
360 specified in the throw clause. When a <code>throw()</code>
361 clause is needed, include it on the method declaration and definition.
362 </li>
363 <li>Use <code>const</code> declarations liberally,
364 but not on "plain old data type" parameters.</li>
365 <li>Catch exceptions by const reference when feasible.</li>
366 <li>Avoid inlining of large functions.</li>
367 <li>Avoid committing binary files to CVS.</li>
368 <li>Resolve compile warnings.</li>
369 <li>Define variables as late as possible.
370 A single object initialization is more efficient than initialization
371 followed by assignment. For example, this logic involves just a single
372 String construction:
373 <pre><code> String s = foo();</code></pre>
374 while this logic causes two String constructions and an assignment:
375 <pre><code> String s;
376 ...
377 s = foo();</code></pre>
378 </li>
379 marek 1.1 <li>Present resources as part of classes, do not use them directly.</li>
380 <li>Use <code>new</code> and <code>delete</code> to manage dynamic
381 memory, not <code>malloc</code>, <code>free</code>, or
382 <code>strdup</code>.</li>
383 <li>When rethrowing an exception from a <code>catch</code>
384 block, avoid specifying the object to throw so that exception subtype
385 information is not lost and construction of an extra exception
386 object is avoided. Do this:
387 <pre><code> catch (Exception&)
388 {
389 ...
390 throw;
391 }</code></pre>
392 Not this:
393 <pre><code> catch (Exception& e)
394 {
395 ...
396 throw e;
397 }</code></pre></li>
398 <li>Do not check whether a pointer is non-null before
399 deleting it. The check is unnecessary, since it is also performed by
400 marek 1.1 the <code>delete</code> operator. Do this:
401 <pre><code> delete ptr;</code></pre>
402 Not this:
403 <pre><code> if (ptr)
404 {
405 delete ptr;
406 }</code></pre></li>
407 <li>Avoid using the compiler default implementations for
408 default constructors, copy constructors, and assignment operators.
409 These should be declared as private and left unimplemented if they
410 are not intended to be used. A decision to use a compiler default
411 should be documented with a comment in the class declaration.</li>
412 <li>Avoid the use of optional parameters in methods which
413 have interface compatibility requirements.</li>
414 <li>Avoid reading variables from the environment in
415 production (not debug or test) runtime code.</li>
416 <li>Definitions for the external interface declarations should not appear
417 in the external interface header files. Implementation logic for the
418 external interfaces should be contained in the associated source files.
419 </li>
420 <li>Pass object parameters by reference, when feasible,
421 marek 1.1 to avoid unnecessary copy constructions. For example, this:
422 <pre><code> void func(const String& s);</code></pre>
423 is preferred to this:
424 <pre><code> void func(String s);</code></pre></li>
425 <li>Avoid using the C++ standard template library (STL) and the standard
426 <code>string</code> class. (These tend to produce bloat and may have
427 portability issues.) These files should not be included:
428 <code><string></code>,
429 <code><vector></code>,
430 <code><map></code>,
431 <code><mmap></code>,
432 <code><set></code>,
433 <code><mset></code>,
434 <code><stack></code>,
435 <code><queue></code>,
436 and other STL header files.</li>
437 <li>Do not call <code>assert()</code> directly. Instead, use
438 <code>PEGASUS_ASSERT()</code> in production code and
439 <code>PEGASUS_TEST_ASSERT()</code> in test programs.</li>
440 <li>Do not explicitly initialize Pegasus Strings to
441 <code>String::EMPTY</code>. This is the default value.</li>
442 marek 1.1 <li>Do not add a null terminator to Pegasus Buffer strings.
443 <code>Buffer::getData()</code> ensures the resulting string is
444 null-terminated.</li>
445 </ol>
446
447 <h3>Documentation</h3>
448 <ol>
449 <li>Class members and methods should be documented with DOC++ comments.</li>
450 <li>Use <code>/** */</code> rather than <code>///</code> for DOC++
451 comments.
452 </li>
453 <li>Use this comment style for DOC++ comments:
454 <pre><code> class X
455 {
456 public:
457
458 /**
459 Creates widgets.
460 @param numWidgets The number of widgets to create.
461 @return true if successful, false otherwise.
462 */
463 marek 1.1 Boolean createWidgets(Uint32 numWidgets);
464 };</code></pre>
465 </li>
466 <li>A description should end with a period, even if it is brief:
467 <pre><code> /**
468 Does something useful.
469 */</code></pre>
470 </li>
471 <li>Add a blank line between documented methods:
472 <pre><code> /**
473 Does something quite useful.
474 */
475 void f();
476
477 /**
478 The previous method has a newline after it
479 to improve its visibility.
480 */
481 void g();</code></pre>
482 </li>
483 </ol>
484 marek 1.1
485 <h3>Portability Considerations</h3>
486 <ol>
487 <li>The use of platform specific <code>#ifdef</code>'s should be minimized
488 and discouraged. It is preferred to abstract the mechanics of
489 dissimilar platforms in separate modules (such as DirPOSIX.cpp vs.
490 DirWindows.cpp) or by using abstraction functions or macros such as
491 those that appear below.</li>
492 <li>In header files, identifiers from the standard library (such as
493 <code>ostream</code>, <code>istream</code>, <code>cout</code>, and
494 <code>cerr</code>) must be enclosed in a <code>PEGASUS_STD()</code>
495 macro (which prepends <code>std::</code> to the argument on some
496 platforms).
497 </li>
498 <li>Do not use the <code>PEGASUS_STD()</code> macro in a source file.
499 Instead, specify <code>PEGASUS_USING_STD;</code> at the beginning of
500 the file.
501 </li>
502 <li>Do not use <code>PEGASUS_USING_STD;</code> or
503 <code>PEGASUS_USING_PEGASUS;</code> in a header file.
504 </li>
505 marek 1.1 <li>Avoid use of conditional compilation for obscuring platform
506 differences. Use platform abstractions in the appropriate platform
507 files or in the System*.cpp files in Common.
508 </li>
509 <li>Windows requires symbols to be explicitly imported/exported from
510 dynamic libraries. Linkage.h files are used to define the necessary
511 linkage macros. Each dynamic library that exports symbols should
512 define a <code>PEGASUS_<LIBRARY>_LINKAGE</code> symbol in a
513 Linkage.h file. Each symbol that is exported from the library
514 must be declared with this linkage macro. For example:
515 <pre><code> class PEGASUS_COMMON_LINKAGE String;
516
517 PEGASUS_COMMON_LINKAGE void globalFunction();</code></pre>
518 </li>
519 <li>A <code>main()</code> function must return an int (required by
520 Windows NT).
521 </li>
522 <li>Do not use <code>ultostr()</code>; use <code>sprintf()</code>
523 instead.
524 </li>
525 <li>Do not declare a throw clause without parentheses:
526 marek 1.1 <pre><code> void f() throw TooBad;</code></pre>
527 </li>
528 <li>Do not include a definition of a static member with its declaration:
529 <pre><code> class X
530 {
531 public:
532
533 static const Uint32 COLOR = 225;
534 };</code></pre>
535 Use this instead:
536 <pre><code> class X
537 {
538 public:
539
540 static const Uint32 COLOR;
541 };</code></pre>
542 And add the definition in the source file:
543 <pre><code> const Uint32 X::COLOR = 225;</code></pre>
544 </li>
545 <li>Use <code>PEGASUS_64BIT_CONVERSION_WIDTH</code> for
546 printf and scanf conversions of 64-bit integers rather than
547 marek 1.1 <code>ll</code> or <code>L</code>.
548 Do this:
549 <pre><code> Sint64 i64 = 10;
550 printf("i64 value = %" PEGASUS_64BIT_CONVERSION_WIDTH "d.\n", i64);</code></pre>
551 Instead of this:
552 <pre><code> Sint64 i64 = 10;
553 printf("i64 value = %lld.\n", i64);</code></pre>
554 </li>
555 <li>Do not include class scoping on methods or members in a class definition.
556 Do this:
557 <pre><code> class X
558 {
559 public:
560
561 int myMethod();
562 };</code></pre>
563 Not this:
564 <pre><code> class X
565 {
566 public:
567
568 marek 1.1 int X::myMethod();
569 };</code></pre>
570 </li>
571 <li>Do not use <code>Pegasus::</code> to scope symbols. Not all platforms
572 support C++ namespaces, and this will cause a compilation failure. If
573 a symbol must be explicitly scoped to the Pegasus namespace, use the
574 <code>PEGASUS_NAMESPACE()</code> macro instead.</li>
575 <li>Use consistent declarations of <code>const</code> parameters in method
576 declarations and definitions.</li>
577 </ol>
578
579
580 <h2><font color="#000000">Discussion</font></h2>
581 <p>Suggestions for additional conventions are listed here for discussion:
582 <ul>
583 <li>Handling of error conditions (cerr vs. logging) and exceptions</li>
584 <li>Testing (perhaps reference another document)</li>
585 <li>Is it appropriate to make a statement about defining
586 localizable messages in the appropriate message bundle?
587 </li>
588 </ul>
589 marek 1.1 </p>
590
591
592 <hr>
593 <p><i><font size="2">Copyright (c) 2005 EMC Corporation; Hewlett-Packard
594 Development Company, L.P.; IBM Corp.; The Open Group;
595 VERITAS Software Corporation</font><br>
596 <br>
597 <font size="1">Permission is hereby granted, free of charge, to any person
598 obtaining a copy of this software and associated documentation files
599 (the "Software"), to deal in the Software without restriction,
600 including without limitation the rights to use, copy, modify, merge, publish,
601 distribute, sublicense, and/or sell copies of the Software, and to permit
602 persons to whom the Software is furnished to do so, subject to the following
603 conditions:</font><br>
604 <font size="2"><br>
605 </font>
606 <font size="1">THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE
607 INCLUDED IN ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS
608 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
609 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
610 marek 1.1 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
611 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
612 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
613 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
614 SOFTWARE.</font></i></p>
615 <hr>
616 <p>Template last modified: <b>March 9th 2004</b> by <b>Martin Kirk<br>
617 </b>Template version: <b>1.8</b></p>
618
619 </body>
620
621 </html>
|