diff options
Diffstat (limited to 'etc/ACE-guidelines.html')
-rw-r--r-- | etc/ACE-guidelines.html | 499 |
1 files changed, 0 insertions, 499 deletions
diff --git a/etc/ACE-guidelines.html b/etc/ACE-guidelines.html deleted file mode 100644 index 784951d1107..00000000000 --- a/etc/ACE-guidelines.html +++ /dev/null @@ -1,499 +0,0 @@ -<!-- $Id$ --> - -<html> - <head> - <title>ACE Software Development Guidelines</title> - <link rev=made href="mailto:levine@cs.wustl.edu"> - </head> - -<BODY text = "#000000" -link="#000fff" -vlink="#ff0f0f" -bgcolor="#ffffff"> - -<center> - <h1>ACE Software Development Guidelines</h1> - <font size=-1> - Last modified <!--#echo var="LAST_MODIFIED" -->.<p> - </font> -</center> -<h2> </h2> - -Thanks to Graham Dumpleton <grahamd@nms.otc.com.au> for providing -corrections to the OSE Classtools link and description. Thanks also -to Graham for providing the OSE tools! - -<p><HR><P> -<h3>Coding Guidelines</h3> -<ul> - <li><strong>General</strong><p> - <ul> - <li>Every text file must end with a newline.<p> - - <li>Use spaces instead of tabs, except in Makefiles. Emacs users - can add this to their <strong>.emacs</strong>: - - <pre>(setq-default indent-tabs-mode nil)</pre></p> - - 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><p> - - <li>Every program should have a ``usage'' message. It should be - printed out if erroneous command line arguments, or a - <strong><code>-?</code></strong> command line argument, are - provided to the program.<p> - - <li>The program <strong><code>main</code></strong> function should - always be declared with arguments, e.g., - <pre> - int - main (int argc, char *argv[]) - { - [...] - - return 0; - } - </pre><p> - - It should also return 0 on successful termination, and non-zero - otherwise.<p> - - <li>Avoid use of floating point types (float and double) and operations - unless absolutely necessary. Not all ACE platforms support them. - Therefore, whereever they are used, ACE_LACKS_FLOATING_POINT - conditional code must be also be used. - </ul> - - <li><strong>Code Documentation</strong><p> - <ul> - <li>Use comments and whitespace (:-) liberally.<p> - - <li>Insert a CVS/RCS keyword string at the top of every source file, - Makefile, config file, <em>etc</em>. For C++ files, it is: - <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;' <em>file</em> - </pre><p> - - <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.<p> - - Please note that the Classinfo tools in OSE have been developed - independently since the copies in ACE were made and thus they - support new features not supported in the ACE version of the tools. - Certain subtle changes were also made in the ACE copies for - indicating sections, <em>etc.</em>, which makes them different - from the OSE documentation. Please see the - <a href=http://www.cs.wustl.edu/~schmidt/ACE-doctools.html>ACE-doctools - page</a> for descriptions of these changes.<p> - </ul> - - <li><strong>Preprocessor</strong><p> - <ul> - <li>Never #include standard headers directly, except in a few - specific ACE files, <em>e.g.</em>, 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.<p> - - <li>Always follow a preprocessor <strong><code>#endif</code></strong> - with a <strong><code>/* */</code></strong> C-style comment. It - should correspond to the condition in the matching - <strong><code>#if</code></strong> directive. For example, - <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><p> - - <li>Always insert a <strong><code>/**/</code></strong> between an - <strong><code>#include</code></strong> and - <strong><code>filename</code></strong>, as shown in the above - example. This avoids dependency problems with Visual C++.<p> - </ul> - - <li><strong>C++ Syntax and Constructs</strong><p> - <ul> - <li><strong><code>for</code></strong> loops should look like: - <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 ACE_ASSERT:) - <pre> - for (size_t i = 0; i < Options::instance ()->spawn_count (); i++) - { - ACE_ASSERT (spawn () == 0); - } - </pre><p> - - Similarly, <strong><code>if</code></strong> statements should have - a space after the ``<strong>if</strong>'', and no spaces just after - the opening parenthesis and just before the closing parenthesis.<p> - - <li>Avoid unnecessary parenthesis. We're not writing Lisp :-)<p> - - <li>Put inline member functions in a <strong><code>.i</code></strong> - file. That file is conditionally included by both the - <strong><code>.h</code></strong> file, for example:<p> - - <pre> - class ACE_Export ACE_High_Res_Timer - { - [...] - }; - - #if defined (__ACE_INLINE__) - #include "ace/High_Res_Timer.i" - #endif /* __ACE_INLINE__ */ - </pre><p> - - and <strong><code>.cpp</code></strong> file:<p> - - <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><p> - - <strong>NOTE:</strong> 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 <code>g++</code> with the - <code>-Wall</code> option, will issue warnings for violations.<p> - - <li>Mutators and accessors should be of this form:<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><p> - - instead of the ``set_'' and ``get_'' form.<p> - - <li>Never use <strong><code>delete</code></strong> to deallocate - memory that was allocated with <strong><code>malloc</code></strong>. - Similarly, never associate <strong><code>free</code></strong> with - <strong><code>new</code></strong>. - <strong><code>ACE_NEW</code></strong> or - <strong><code>ACE_NEW_RETURN</code></strong> should be used to - allocate memory, and <strong><code>delete</code></strong> should - be used to deallocate it. And be careful to use the correct form, - <strong><code>delete</code></strong> or - <strong><code>delete []</code></strong> to correspond to the - allocation.<p> - - <li>Always use <strong><code>ACE_NEW</code></strong> or - <strong><code>ACE_NEW_RETURN</code></strong> to allocate memory, - because they check for successful allocation and set errno - appropriately if it fails.<p> - - <li>Never compare or assign a pointer value with <strong>NULL</strong>; - use <strong>0</strong> instead. The language allows any pointer to - be compared or assigned with <strong>0</strong>. The definition - of <strong>NULL</strong> is implementation dependent, so it is - difficult to use portably without casting.<p> - - <li>Never cast a pointer to or from an <strong><code>int</code></strong>. - On all currently supported ACE platforms, it is safe to cast - a pointer to or from a <strong><code>long</code></strong>.<p> - - <li>Be very careful when selecting an integer type that must be a - certain size, <em>e.g.</em>, 4 bytes. <strong>long</strong> 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.<p> - - <li>If a class has any virtual functions, and its destructor is - declared explicitly in the class, then the destructor should - <strong>always</strong> 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 <strong>not be inline</strong>. (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.)<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.<p> - - <li>Initialization is usually cleaner than assignment, especially - in a conditional. So, instead of writing code like this: - - <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><p> - - 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.<p> - - <li>It is usually clearer to write conditionals that have - both branches without a negated condition. For example,<p> - - <pre> - if (test) - { - // true branch - } - else - { - // false branch - } - </pre><p> - - is preferred over:<p> - - <pre> - if (! test) - { - // false test branch - } - else - { - // true test branch - } - </pre><p> - - <li>If a cast is necessary, avoid use of ANSI-style casts, - <em>e.g.</em>, <code>int (foo)</code>. Instead, use - the ACE_static_cast macro: - - <pre> - return ACE_static_cast(size_t, this->count_) > that->size_; - </pre><p> - - <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: - - <pre> - // Disallow copying by not implementing the following . . . - ACE_Object_Manager (const ACE_Object_Manager &); - ACE_Object_Manager &operator= (const ACE_Object_Manager &); - </pre><p> - - If the class is a template class, then the - <code>ACE_UNIMPLEMENTED_FUNC</code> 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><p> - - <code>ACE_UNIMPLEMENTED_FUNC</code> can be used with non-template - classes as well. Though for consistency and maximum safety, it - should be avoided for non-template classes.<p> - </ul> - - <li><strong>I/O</strong><p> - <ul> - <li>Use <strong><code>ACE_DEBUG</code></strong> for printouts, - and <strong><code>ACE_OS::scanf/fprintf ()</code></strong> for - file I/O. Avoid using iostreams because of implementation - differences across platforms.<p> - </ul> - - <li><strong>UNICODE conformity</strong><p> - - <ul> - <li>Define strings as <strong><code>ASYS_TCHAR</code></strong> if - they need to be passed into system API. It expands to - <code>wchar_t</code> only when - <code>ACE_HAS_MOSTLY_UNICODE_APIS</code> is deined.<p> - - <li>Use <strong><code>ASYS_TEXT</code></strong> and - <strong><code>ASYS_WIDE_STRING</code></strong> for format - strings and other string arguments passed to - <code>ACE_DEBUG</code> or <code>ACE_ERROR</code>. For - example,<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> - <p> - 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.<p> - - <li><strong><code>ACE_TRACE</code></strong> handles conversion - between char strings and UNICODE strings automatically.<p> - - <li>Other helper macros include - <strong><code>ASYS_MULTIBYTE_STRING</code></strong> and - <strong><code>ASYS_ONLY_MULTIBYTE_STRING</code></strong>. See - the end of <a href="../ace/OS.h">OS.h</a> for more details.<p> - - </ul><p> - -</ul><p> - -<p><HR><P> - -<h3><a href="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">ACE</a> - Usage Guidelines</h3> -<ul> - <li>Always use <strong><code>ACE_OS</code></strong> (static) - member functions instead of bare OS system calls.<p> - - <li>Use the <strong><code>ACE_SYNCH_MUTEX</code></strong> macro, - instead of using one of the specific mutexes, such as - <strong><code>ACE_Thread_Mutex</code></strong>. This provides - portability between threaded and non-threaded platforms.<p> - - <li>Avoid creating a static instance of user-defined (class) type. - Instead, either create it as an - <strong><code>ACE_Singleton</code></strong>, - <strong><code>ACE_TSS_Singleton</code></strong>, or as an - <strong><code>ACE_Cleanup</code></strong> object. See the - <strong>ACE</strong> - <a href="../ace/Singleton.h"><code>Singleton.h</code></a>, - <a href="../ace/Object_Manager.h"><code>Object_Manager.h</code></a>, and - <a href="../ace/Managed_Object.h"><code>Managed_Object.h</code></a> - header files for more information.<p> - - Static instances of built-in types, such as - <strong><code>int</code></strong> or any pointer type, are fine.<p> - - Construction of static instance of a user-defined type should - <em>never</em> 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.<p> - - <li>Do not use run-time type identification (RTTI). Some platforms - do not support it.<p> - - <li>Do not use exception handling. Some platforms do not support it. - And, it imposes an execution speed penalty.<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: - - <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 - <a href="../ace/Naming_Context.cpp"><code>ACE_Naming_Context</code></a>. - All failed constructors in ACE (should) call ACE_ERROR. This sets - the thread specific <strong>op_status</strong>, 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.<p> - - <li>Avoid using the C++ Standard Template Library (STL) in our - applications. Some platforms do not support it yet.<p> -</ul><p> - - -<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.<p> -</ul> - -<p><HR><P> - -<h3>Software Engineering Guidelines</h3> -<ul> - <li><strong>Advise</strong>: Keep other developers informed of problems - and progress.<p> - - <li><strong>Authorize</strong>: We have contractual obligations to not - unilaterally change interfaces. If you need to change or remove an - interface, get an OK.<p> - - <li><strong>Minimize</strong> risk: Test all changes. Solicit review of - changes.<p> - - <li><strong>Revise</strong> only when necessary: Every change has risk, - so avoid making any change unless there is a good reason for it.<p> - - <li><strong>Normalize</strong>: Factor out commonality. For example, - maintain a data value in only one place.<p> - - <li><strong>Synthesize</strong>: 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.<p> -</ul><p> - -<p> -<HR><P> -<h3><a href="http://www.cs.wustl.edu/~schmidt/rules.html">ACE - Design Rules</a></h3> - -<hr> -<!-- hhmts start --> -Last modified: Thu Apr 30 12:36:31 CDT 1998 -<!-- hhmts end --> - -</body> -</html> |