diff options
Diffstat (limited to 'docs/ACE-guidelines.html')
-rw-r--r-- | docs/ACE-guidelines.html | 1048 |
1 files changed, 0 insertions, 1048 deletions
diff --git a/docs/ACE-guidelines.html b/docs/ACE-guidelines.html deleted file mode 100644 index 7132e79d18a..00000000000 --- a/docs/ACE-guidelines.html +++ /dev/null @@ -1,1048 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.5 [en] (WinNT; I) [Netscape]"> - <title>ACE Software Development Guidelines</title> -<!-- $Id$ --> -<link rev=made href="mailto:levine@cs.wustl.edu"> -</head> -<body text="#000000" bgcolor="#FFFFFF" link="#000FFF" vlink="#FF0F0F"> - -<hr> -<h3> -ACE Software Development Guidelines</h3> - -<ul> -<li> -<b>General</b></li> - -<br> -<p> -<ul> -<li> -Every text file must end with a newline.</li> - -<br> -<p> -<li> -Use spaces instead of tabs, except in Makefiles. Emacs users can add this -to their <b>.emacs</b>:</li> - -<pre>(setq-default indent-tabs-mode nil)</pre> -Microsoft Visual C++ users should do the following: -<pre> Choose: Tools -- Options -- Tabs - Then Set: "Tab size" to 8 and "Indent size" to 2, and - indent using spaces. -</pre> - -<li> -If you add a comment to code that is directed to, or requires the attention -of, a particular individual: <b>SEND EMAIL TO THAT INDIVIDUAL!</b>.</li> - -<br> -<p> -<li> -Every program should have a ``usage'' message. It should be printed out -if erroneous command line arguments, or a <b><tt>-?</tt></b> command line -argument, are provided to the program.</li> - -<br> -<p> -<li> -The program <b><tt>main</tt></b> function must always be declared with -arguments, <i>e.g.</i>,</li> - -<pre> int - main (int argc, char *argv[]) - { - [...] - - return 0; - } -</pre> -If you don't use the <tt>argc</tt> and/or <tt>argv</tt> arguments, don't -declare them, <i>e.g.</i>, -<pre> int - main (int, char *[]) - { - [...] - - return 0; - } -</pre> -Please declare the second argument as <tt>char *[]</tt> instead of <tt>char -**</tt>. Ancient versions of MSC complained about <tt>char **</tt>; I've -never seen a C++ compiler complain about <tt>char *[]</tt>. -<p> <tt>main</tt> must also return 0 on successful termination, and -non-zero otherwise. -<br> -<br> -<li> -Avoid use of floating point types (float and double) and operations unless -absolutely necessary. Not all ACE platforms support them. Therefore, wherever -they are used, ACE_LACKS_FLOATING_POINT conditional code must be also be -used.</li> - -<br> -<p> </ul> - -<li> -<b>Code Documentation</b></li> - -<br> -<p> -<ul> -<li> -Use comments and whitespace (:-) liberally. Comments should consist of -complete sentences, <i>i.e.</i>, start with a capital letter and end with -a period.</li> - -<br> -<p> -<li> -Insert a CVS/RCS keyword string at the top of every source file, Makefile, -config file, <i>etc</i>. For C++ files, it is:</li> - -<pre> // $<!-- -->Id$ -</pre> -It is not necessary to fill in the fields of the keyword string, or modify -them when you edit a file that already has one. CVS does that automatically -when you checkout or update the file. -<p> To insert that string at the top of a file: -<pre> perl -pi -e \ - 'if (! $o) {printf "// \$<!-- -->Id\$\n\n";}; $o = 1;' <i>file -</i></pre> - -<li> -Comments, especially in header files, must follow the <a href="http://www.dscpl.com.au">OSE</a> -Tools format requirements. Please see the ``Classinfo Tools'' section of -the <a href="http://www.dscpl.com.au">OSE</a> ``Tools Manual'' for these -requirements.</li> - -<br> -<p> </ul> - -<li> -<b>Preprocessor</b></li> - -<br> -<p> -<ul> -<li> -Never #include standard headers directly, except in a few specific ACE -files, <i>e.g.</i>, OS.h and stdcpp.h. Let those files #include the correct -headers. If you do not do this, your code will not compile with the Standard -C++ Library.</li> - -<br> -<p> -<li> -Always follow a preprocessor <b><tt>#endif</tt></b>with a <b><tt>/* */</tt></b> -C-style comment. It should correspond to the condition in the matching -<b><tt>#if</tt></b> directive. For example,</li> - -<pre> #if defined (ACE_HAS_THREADS) - # if defined (ACE_HAS_STHREADS) - # include /**/ <synch.h> - # include /**/ <thread.h> - # define ACE_SCOPE_PROCESS P_PID - # define ACE_SCOPE_LWP P_LWPID - # define ACE_SCOPE_THREAD (ACE_SCOPE_LWP + 1) - # else - # define ACE_SCOPE_PROCESS 0 - # define ACE_SCOPE_LWP 1 - # define ACE_SCOPE_THREAD 2 - # endif /* ACE_HAS_STHREADS */ - #endif /* ACE_HAS_THREADS */ -</pre> - -<li> -Always insert a <b><tt>/**/</tt></b> between an <b><tt>#include</tt></b> -and <b><tt>filename</tt></b>, as shown in the above example. This avoids -dependency problems with Visual C++.</li> - -<br> -<p> -<li> -Be very careful with names of macros and enum values. It's always best -to prefix them with something like <tt>ACE_</tt> or <tt>TAO_</tt>. There -are too many system headers out there that #define <tt>OK</tt>, <tt>SUCCESS</tt>, -<tt>ERROR</tt>, and so on.</li> - -<br> -<p> -<li> -Try to centralize <tt>#ifdefs</tt> with <tt>typedefs</tt> and <tt>#defines</tt>. -For example, use this:</li> - -<pre> #if defined(ACE_PSOS) - typedef long ACE_NETIF_TYPE; - # define ACE_DEFAULT_NETIF 0 - #else /* ! ACE_PSOS */ - typedef const ASYS_TCHAR* ACE_NETIF_TYPE; - # define ACE_DEFAULT_NETIF ASYS_TEXT("le0") - #endif /* ! ACE_PSOS */ -</pre> -instead of: -<p>#if defined (ACE_PSOS) // pSOS supports numbers, not names for network -interfaces long net_if, #else /* ! ACE_PSOS */ const ASYS_TCHAR *net_if, -#endif /* ! ACE_PSOS */ -<li> -Protect header files against multiple inclusion with this construct:</li> - -<pre> #ifndef FOO_H - #define FOO_H - - [contents of header file] - - #endif /* FOO_H */ -</pre> -This exact construct (note the <tt>#ifndef</tt>) is optimized by many compilers -such they only open the file once per compilation unit. Thanks to Eric -C. Newton <ecn@smart.net> for pointing that out. -<p> If the header <tt>#includes</tt> an ACE library header, then it's -a good idea to include the <tt>#pragma once</tt> directive: -<pre> #ifndef FOO_H - #define FOO_H - - #include "ace/ACE.h" - #if !defined (ACE_LACKS_PRAGMA_ONCE) - # pragma once - #endif /* ACE_LACKS_PRAGMA_ONCE */ - - [contents of header file] - - #endif /* FOO_H */ -</pre> -<tt>#pragma once</tt> must be protected, because some compilers complain -about it. The protection depends on <tt>ACE_LACKS_PRAGMA_ONCE</tt>, which -is defined in some ACE config headers. Therefore, the protected <tt>#pragma -once</tt> construct should only be used after an <tt>#include</tt> of an -ACE library header. Note that many compilers enable the optimization if -the <tt>#ifndef</tt> protection construct is used, so for them, <tt>#pragma -once</tt> is superfluous. -<p> <b>No</b> code can appear after the final <tt>#endif</tt> for -the optimization to be effective and correct. -<br> -<br> -<p>Files that contain parametric classes should follow this style: -<pre> #ifndef FOO_T_H - #define FOO_T_H - - #include "ace/ACE.h" - #if !defined (ACE_LACKS_PRAGMA_ONCE) - # pragma once - #endif /* ACE_LACKS_PRAGMA_ONCE */ - - // Put your template declarations here... - - #if defined (__ACE_INLINE__) - #include "Foo_T.i" - #endif /* __ACE_INLINE__ */ - - #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) - #include "Foo_T.cpp" - #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - - #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) - #pragma implementation "Foo_T.cpp" - #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - - #endif /* FOO_T_H */</pre> -Notice that some compilers need to see the code of the template, hence -the <tt>.cpp</tt> file must be included from the header file. -<p>To avoid multiple inclusions of the <tt>.cpp</tt> file it should also -be protected as in: -<pre> #ifndef FOO_T_C - #define FOO_T_C - - #include "Foo_T.h" - #if !defined (ACE_LACKS_PRAGMA_ONCE) - # pragma once - #endif /* ACE_LACKS_PRAGMA_ONCE */ - - #if !defined (__ACE_INLINE__) - #include "ace/Active_Map_Manager_T.i" - #endif /* __ACE_INLINE__ */ - - ACE_RCSID(lib, Foo_T, "$<!-- -->Id$") - - // put your template code here - - #endif /* FOO_T_H */</pre> -Finally you may want to include the template header file from a non-template -header file (check <tt>$ACE_ROOT/ace/Synch.h</tt>); in such a case the -template header should be included <b>after</b> the inline function definitions, -as in: -<pre> #ifndef FOO_H - #define FOO_H - - #include "ace/ACE.h" - #if !defined (ACE_LACKS_PRAGMA_ONCE) - # pragma once - #endif /* ACE_LACKS_PRAGMA_ONCE */ - - // Put your non-template declarations here... - - #if defined (__ACE_INLINE__) - #include "Foo.i" - #endif /* __ACE_INLINE__ */ - - #include "Foo_T.h" - - #endif /* FOO_H */</pre> -</ul> - -<li> -<b>C++ Syntax and Constructs</b></li> - -<br> -<p> -<ul> -<li> -<b><tt>for</tt></b> loops should look like:</li> - -<pre> for (size_t i = 0; i < Options::instance ()->spawn_count (); ++i) - spawn (); -</pre> -Though, I prefer to always wrap the body of the loop in braces, to avoid -surprises when other code or debugging statements are added, and to maintain -sanity when the body consists of a macro, such as an ACE_ASSERT without -a trailing semicolon: -<pre> for (size_t i = 0; i < Options::instance ()->spawn_count (); ++i) - { - ACE_ASSERT (spawn () == 0;) - } -</pre> -Similarly, <b><tt>if</tt></b> statements should have a space after the -``<b>if</b>'', and no spaces just after the opening parenthesis and just -before the closing parenthesis. -<br> -<br> -<li> -If a loop index is used after the body of the loop, it <b>must</b> be declared -before the loop. For example,</li> - -<pre> size_t i = 0; - for (size_t j = 0; file_name [j] != '\0'; ++i, ++j) - { - if (file_name [j] == '\\' && file_name [j + 1] == '\\') - ++j; - - file_name [i] = file_name [j]; - } - - // Terminate this string. - file_name [i] = '\0'; -</pre> - -<li> -Prefix operators are sometimes more efficient than postfix operators. Therefore, -they are preferred over their postfix counterparts where the expression -value is not used.</li> - -<p><br> Therefore, use this idiom for iterators, with prefix operator -on the loop index: -<pre> ACE_Ordered_MultiSet<int> set; - ACE_Ordered_MultiSet_Iterator<int> iter(set); - - for (i = -10; i < 10; ++i) - set.insert (2 * i + 1); - -</pre> -rather than the postfix operator: -<pre> for (i = -10; i < 10; i++) - set.insert (2 * i + 1); -</pre> - -<li> -When a class provides operator==, it must also provide operator!=. Also, -both these operators must be const.</li> - -<li> -Avoid unnecessary parenthesis. We're not writing Lisp :-)</li> - -<br> -<p> -<li> -Put inline member functions in a <b><tt>.i</tt></b> file. That file is -conditionally included by both the <b><tt>.h</tt></b> file, for example:</li> - -<br> -<p> -<pre> class ACE_Export ACE_High_Res_Timer - { - [...] - }; - - #if defined (__ACE_INLINE__) - #include "ace/High_Res_Timer.i" - #endif /* __ACE_INLINE__ */ -</pre> -and <b><tt>.cpp</tt></b> file: -<br> -<br> -<pre> #define ACE_BUILD_DLL - #include "ace/High_Res_Timer.h" - - #if !defined (__ACE_INLINE__) - #include "ace/High_Res_Timer.i" - #endif /* __ACE_INLINE__ */ - - ACE_ALLOC_HOOK_DEFINE(ACE_High_Res_Timer) -</pre> -<b>NOTE:</b> It is very important to ensure than an inline function will -not be used before its definition is seen. Therefore, the inline functions -in the .i file should be arranged properly. Some compilers, such as <tt>g++</tt> -with the <tt>-Wall</tt> option, will issue warnings for violations. -<br> -<br> -<li> -<tt>ACE_Export</tt> must be inserted between the <tt>class</tt> keyword -and class name for all classes that are exported from libraries, as shown -in the example above. <b>However</b>, do <b>not</b> use <tt>ACE_Export</tt> -for template classes!</li> - -<br> -<p> -<li> -Mutators and accessors should be of this form:</li> - -<br> -<p> -<pre> void object_addr (const ACE_INET_Addr &); - // Sets <object_addr_> cache from <host> and <port>. - - ACE_INET_Addr &object_addr (void); - // Returns the <ACE_INET_Addr> for this profile. -</pre> -instead of the ``set_'' and ``get_'' form. -<br> -<br> -<li> -Never use <b><tt>delete</tt></b> to deallocate memory that was allocated -with <b><tt>malloc</tt></b>. Similarly, never associate <b><tt>free</tt></b> -with <b><tt>new</tt></b>. <b><tt>ACE_NEW</tt></b> or <b><tt>ACE_NEW_RETURN</tt></b> -should be used to allocate memory, and <b><tt>delete</tt></b> should be -used to deallocate it. And be careful to use the correct form, <b><tt>delete</tt></b> -or <b><tt>delete []</tt></b> to correspond to the allocation.</li> - -<br> -<p> -<li> -Don't check for a pointer being 0 before deleting it. It's always safe -to delete a 0 pointer. If the pointer is visible outside the local scope, -it's often a good idea to 0 it _after_ deleting it. Note, the same argument -applies to free().</li> - -<br> -<p> -<li> -Always use <b><tt>ACE_NEW</tt></b> or <b><tt>ACE_NEW_RETURN</tt></b> to -allocate memory, because they check for successful allocation and set errno -appropriately if it fails.</li> - -<br> -<p> -<li> -Never compare or assign a pointer value with <b>NULL</b>; use <b>0</b> -instead. The language allows any pointer to be compared or assigned with -<b>0</b>. The definition of <b>NULL</b> is implementation dependent, so -it is difficult to use portably without casting.</li> - -<br> -<p> -<li> -Never cast a pointer to or from an <b><tt>int</tt></b>. On all currently -supported ACE platforms, it is safe to cast a pointer to or from a <b><tt>long</tt></b>.</li> - -<br> -<p> -<li> -Be very careful when selecting an integer type that must be a certain size, -<i>e.g.</i>, 4 bytes. <b>long</b> is not 4 bytes on all platforms; it is -8 bytes on many 64-bit machines. ACE_UINT32 is always 4 bytes, and ACE_UINT64 -is always 8 bytes.</li> - -<br> -<p> -<li> -If a class has any virtual functions, and its destructor is declared explicitly -in the class, then the destructor should <b>always</b> be virtual as well. -And to support compiler activities such as generation of virtual tables -and, in some cases, template instantiation, the virtual destructor should -<b>not be inline</b>. (Actually, any non-pure virtual function could be -made non-inline for this purpose. But, for convenience, if its performance -is not critical, it is usually easiest just to make the virtual destructor -non-inline.)</li> - -<br> -<p> -<li> -Constructor initializers must appear in the same order as the data members -are declared in the class header. This avoids subtle errors, because initialization -takes place in the order of member declaration.</li> - -<br> -<p> -<li> -Initialization is usually cleaner than assignment, especially in a conditional. -So, instead of writing code like this:</li> - -<pre> ssize_t n_bytes; - - // Send multicast of one byte, enough to wake up server. - if ((n_bytes = multicast.send ((char *) &reply_port, - sizeof reply_port)) == -1) -</pre> -Write it like this: -<pre> ssize_t n_bytes = multicast.send ((char *) &reply_port, - sizeof reply_port) - - // Send multicast of one byte, enough to wake up server. - if (n_bytes == -1) -</pre> -But, beware if the initialization is of a static variable. A static variable -is only initialized the first time its declaration is seen. Of course, -we should avoid using static variables at all. -<br> -<br> -<li> -It is usually clearer to write conditionals that have both branches without -a negated condition. For example,</li> - -<br> -<p> -<pre> if (test) - { - // true branch - } - else - { - // false branch - } -</pre> -is preferred over: -<br> -<br> -<pre> if (! test) - { - // false test branch - } - else - { - // true test branch - } -</pre> - -<li> -If a cast is necessary, avoid use of function-style casts, <i>e.g.</i>, -<tt>int (foo)</tt>. Instead, use one of the ACE cast macros:</li> - -<pre> return ACE_static_cast(size_t, this->count_) > that->size_; -</pre> -The general usage guidelines for the four styles of casts are: -<br> -<br> -<ul> -<li> -<b>ACE_const_cast</b>: use to cast away constness, or volatile-ness.</li> - -<br> -<p> -<li> -<b>ACE_static_cast</b>: use to cast between compatible types, such as downcasting -a pointer or narrowing an integer.</li> - -<br> -<p> -<li> -<b>ACE_reinterpret_cast</b>: use only when ACE_static_cast is not suitable.</li> - -<br> -<p> -<li> -<b>ACE_dynamic_cast</b>: avoid, unless you really want to type check at -run-time.</li> - -<br> -<p> </ul> - -<li> -In general, if instances of a class should not be copied, then a private -copy constructor and assignment operator should be declared for the class, -but not implemented. For example:</li> - -<pre> // Disallow copying by not implementing the following . . . - ACE_Object_Manager (const ACE_Object_Manager &); - ACE_Object_Manager &operator= (const ACE_Object_Manager &); -</pre> -If the class is a template class, then the <tt>ACE_UNIMPLEMENTED_FUNC</tt> -macro should be used: -<pre> // = Disallow copying... - ACE_UNIMPLEMENTED_FUNC (ACE_TSS (const ACE_TSS<TYPE> &)) - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS<TYPE> &)) -</pre> -<tt>ACE_UNIMPLEMENTED_FUNC</tt> can be used with non-template classes as -well. Though for consistency and maximum safety, it should be avoided for -non-template classes. -<br> -<br> -<li> -Never use <tt>bool</tt>, <tt>BOOL</tt>, or similar types. (CORBA::Boolean -is acceptable). Use <tt>int</tt> or <tt>u_int</tt> instead for boolean -types.</li> - -<br> -<p> -<li> -Functions should always return -1 to indicate failure, and 0 or greater -to indicate success.</li> - -<br> -<p> -<br> -<p>Separate the code of your templates from the code for non-parametric -classes: some compilers get confused when template and non-template code -is mixed in the same file.</ul> - -<li> -<b>I/O</b></li> - -<br> -<p> -<ul> -<li> -Use <b><tt>ACE_DEBUG</tt></b> for printouts, and <b><tt>ACE_OS::scanf/fprintf -()</tt></b> for file I/O. Avoid using iostreams because of implementation -differences across platforms.</li> - -<br> -<p> -<li> -After attempting to open an existing file, always check for success. Take -appropriate action if the open failed.</li> - -<br> -<p> </ul> - -<li> -<b>UNICODE conformity</b></li> - -<br> -<p> -<ul> -<li> -Define strings as <b><tt>ASYS_TCHAR</tt></b> if they need to be passed -into system API. It expands to <tt>wchar_t</tt> only when <tt>ACE_HAS_MOSTLY_UNICODE_APIS</tt> -is defined.</li> - -<br> -<p> -<li> -Use <b><tt>ASYS_TEXT</tt></b> and <b><tt>ASYS_WIDE_STRING</tt></b> for -format strings and other string arguments passed to <tt>ACE_DEBUG</tt> -or <tt>ACE_ERROR</tt>. For example,</li> - -<br> -<p> -<pre> void - ACE_FOO::ace_bar (int err, ASYS_TCHAR *astr) - { - ACE_TRACE ("ACE_FOO::ace_bar"); - - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("From ACE_FOO::ace_bar"))); - - if (err) - ACE_ERROR ((LM_ERROR, - ASYS_TEXT ("(%P) Printing this string %s\n"), - astr)); - } -</pre> -This is because ACE also support platforms which use UNICODE in most of -their APIs. On these platforms, ACE also uses UNICODE as its system string -type. -<br> -<br> -<li> -<b><tt>ACE_TRACE</tt></b> handles conversion between char strings and UNICODE -strings automatically.</li> - -<br> -<p> -<li> -Other helper macros include <b><tt>ASYS_MULTIBYTE_STRING</tt></b> and <b><tt>ASYS_ONLY_MULTIBYTE_STRING</tt></b>. -See the end of <a href="../ace/OS.h">OS.h</a> for more details.</li> - -<br> -<p> </ul> - -<li> -<b>Exceptions</b></li> - -<br> -<p> -<ul> -<li> -There are many ways of throwing and catching exceptions. The code below -gives several examples. Note that each method has different semantics and -costs. Whenever possible, use the first approach.</li> - -<br> -<p> -<pre> #include "iostream.h" - - class exe_foo - { - public: - exe_foo (int data) : data_ (data) - { cerr << "constructor of exception called" << endl; } - ~exe_foo () - { cerr << "destructor of exception called" << endl; } - exe_foo (const exe_foo& foo) : data_ (foo.data_) - { cerr << "copy constructor of exception called" << endl; } - int data_; - }; - - - void - good (int a) - { - throw exe_foo (a); - }; - - void - bad (int a) - { - exe_foo foo (a); - throw foo; - }; - - int main () - { - cout << endl << "First exception" << endl << endl; - try - { - good (0); - } - catch (exe_foo &foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - cout << endl << "Second exception" << endl << endl; - try - { - good (0); - } - catch (exe_foo foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - cout << endl << "Third exception" << endl << endl; - try - { - bad (1); - } - catch (exe_foo &foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - cout << endl << "Fourth exception" << endl << endl; - try - { - bad (1); - } - catch (exe_foo foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - return 0; - } -</pre> -Output is: -<pre> First exception - - constructor of exception called - exception caught: 0 - destructor of exception called - - Second exception - - constructor of exception called - copy constructor of exception called - exception caught: 0 - destructor of exception called - destructor of exception called - - Third exception - - constructor of exception called - copy constructor of exception called - destructor of exception called - exception caught: 1 - destructor of exception called - - Fourth exception - - constructor of exception called - copy constructor of exception called - destructor of exception called - copy constructor of exception called - exception caught: 1 - destructor of exception called - destructor of exception called - -</pre> -</ul> -</ul> - -<hr> -<h3> -<a href="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">ACE</a> Usage -Guidelines</h3> - -<ul> -<li> -Always use <b><tt>ACE_OS</tt></b> (static) member functions instead of -bare OS system calls.</li> - -<br> -<p> -<li> -As a general rule, the only functions that should go into the <b><tt>ACE_OS</tt></b> -class are ones that have direct equivalents on some OS platform. Functions -that are extensions should go in the <b><tt>ACE</tt></b> class.</li> - -<br> -<p> -<li> -Use the <b><tt>ACE_SYNCH_MUTEX</tt></b> macro, instead of using one of -the specific mutexes, such as <b><tt>ACE_Thread_Mutex</tt></b>. This provides -portability between threaded and non-threaded platforms.</li> - -<br> -<p> -<li> -Avoid creating a static instance of user-defined (class) type. Instead, -either create it as an <b><tt>ACE_Singleton</tt></b>, <b><tt>ACE_TSS_Singleton</tt></b>, -or as an <b><tt>ACE_Cleanup</tt></b> object. See the <b>ACE</b> <tt><a href="../ace/Singleton.h">Singleton.h</a></tt>, -<tt><a href="../ace/Object_Manager.h">Object_Manager.h</a></tt>, and <tt><a href="../ace/Managed_Object.h">Managed_Object.h</a></tt> -header files for more information.</li> - -<p><br> Static instances of built-in types, such as <b><tt>int</tt></b> -or any pointer type, are fine. -<p> Construction of static instance of a user-defined type should -<i>never</i> spawn threads. Because order of construction of statics across -files is not defined by the language, it is usually assumed that only one -thread exists during static construction. This allows statics suchs as -locks to be safely created. We do not want to violate this assumption. -<br> -<br> -<li> -Do not use run-time type identification (RTTI). Some platforms do not support -it.</li> - -<br> -<p> -<li> -Do not use C++ exception handling directly. Some platforms do not support -it. And, it can impose an execution speed penalty. Instead use the TAO/ACE -try/catch macros.</li> - -<br> -<p> -<li> -Because ACE does not use exception handling, dealing with failures requires -a bit of care. This is especially true in constructors. Consider the following -approach:</li> - -<pre> ACE_NEW_RETURN (this->name_space_, LOCAL_NAME_SPACE, -1); - - if (ACE_LOG_MSG->op_status () != 0) - .... -</pre> -This snip of code is from <tt><a href="../ace/Naming_Context.cpp">ACE_Naming_Context</a></tt>. -All failed constructors in ACE (should) call ACE_ERROR. This sets the thread -specific <b>op_status</b>, which can be checked by the caller. This mechanism -allows the caller to check for a failed constructor without the requiring -the constructor to throw exceptions. -<br> -<br> -<li> -Avoid using the C++ Standard Template Library (STL) in our applications. -Some platforms do not support it yet.</li> - -<br> -<p> -<li> -Be <i>very</i> careful with <tt>ACE_ASSERT</tt>. It must only be used to -check values; it may never be used to wrap a function call, or contain -any other side effect. That's because the statement will disappear when -ACE_NDEBUG is enabled. For example, this code is BAD:</li> - -<pre> ACE_ASSERT (this->next (retv) != 0); // BAD CODE! -</pre> -Instead, the above should be coded this way: -<pre> int result = this->next (retv); - ACE_ASSERT (result != 0); - ACE_UNUSED_ARG (result); -</pre> - -<li> -Never put side effects in <tt>ACE_DEBUG</tt> code:</li> - -<pre> ACE_DEBUG ((LM_DEBUG, - "handling signal: %d iterations left\n", - --this->iterations_)); // BAD CODE! -</pre> -Note that this won't work correctly if <tt>ACE_NDEBUG</tt> is defined, -for the same reason that having side-effects in <tt>ACE_ASSERT</tt>s won't -work either, <i>i.e.</i>, because the code is removed. -<br> -<br> -<li> -Immediately after opening a temporary file, unlink it. For example:</li> - -<pre> -<tt> ACE_HANDLE h = open the file (filename); - - ACE_OS::unlink (filename); -</tt></pre> -This avoids leaving the temporary file even if the program crashes. -<br> -<br> </ul> - -<hr> -<h3> -<a href="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">Other ACE</a> -and <a href="http://www.cs.wustl.edu/~schmidt/TAO-overview.html">TAO</a> -Guidelines</h3> - -<ul> -<li> -Never add copyrighted, confidential, or otherwise restricted code to the -ACE or TAO distributions without written permission from the owner.</li> - -<li> -A source code filename should never be a (case-insenstitive) duplicate -of another, even if it is in a different directory (or project). Some compilers -will break if this is so.</li> - -<br> -<p> </ul> - -<hr> -<h3> -<a href="http://www.cs.wustl.edu/~levine/CVS.html">CVS</a> Usage Guidelines</h3> - -<ul> -<li> -Always make sure that a change builds and executes correctly on at least -one platform before checking it into the CVS repository.</li> - -<br> -<p> </ul> - -<hr> -<h3> -Script Guidelines</h3> - -<ul> -<li> -In general, it's best to write scripts in Perl. It's OK to use Bourne shell. -Never, never, never use csh, ksh, bash, or any other kind of shell.</li> - -<br> -<p> -<li> -Follow the Perl style guide guide as closely as possible. <tt>man perlstyle</tt> -to view it.</li> - -<li> -Don't specify a hard-coded path to Perl itself. Use the following code -at the top of the script to pick up perl from the users <tt>PATH</tt>:</li> - -<pre> eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; -</pre> - -<li> -Never, never, never start the first line of a script with ``#'', unless -the first line is ``#! /bin/sh''. With just ``#'', t/csh users will spawn -a new shell. That will cause their <tt>.[t]cshrc</tt> to be processed, -possibly clobbering a necessary part of their environment.</li> - -<br> -<p> -<li> -If your Perl script relies on features only available in newer versions -of Perl, include the a statement similar to the following:</li> - -<pre> require 5.003; -</pre> - -<li> -Don't depend on <b><tt>.</tt></b> being in the user's path. If the script -spawns another executable that is supposed to be in the current directory, -be sure the prefix its filename with <b><tt>.</tt></b>.</li> - -<br> -<p> </ul> - -<hr> -<h3> -Software Engineering Guidelines</h3> - -<ul> -<li> -<b>Advise</b>: Keep other developers informed of problems and progress.</li> - -<br> -<p> -<li> -<b>Authorize</b>: We have contractual obligations to not unilaterally change -interfaces. If you need to change or remove an interface, get an OK.</li> - -<br> -<p> -<li> -<b>Minimize</b> risk: Test all changes. Solicit review of changes.</li> - -<br> -<p> -<li> -<b>Revise</b> only when necessary: Every change has risk, so avoid making -any change unless there is a good reason for it.</li> - -<br> -<p> -<li> -<b>Normalize</b>: Factor out commonality. For example, maintain a data -value in only one place.</li> - -<br> -<p> -<li> -<b>Synthesize</b>: Build stubs and scaffolding early to simulate the complete -system. Maintain a checked-in version of the system that cleanly builds -and tests at all times.</li> - -<br> -<p> </ul> - -<hr> -<h3> -<a href="http://www.cs.wustl.edu/~schmidt/rules.html">ACE Design Rules</a></h3> - -<hr> -<p><font size=-1>Last modified <!--#echo var="LAST_MODIFIED" -->.</font> -<br> -<br> -</body> -</html> |