summaryrefslogtreecommitdiff
path: root/etc/ACE-guidelines.html
diff options
context:
space:
mode:
Diffstat (limited to 'etc/ACE-guidelines.html')
-rw-r--r--etc/ACE-guidelines.html367
1 files changed, 0 insertions, 367 deletions
diff --git a/etc/ACE-guidelines.html b/etc/ACE-guidelines.html
deleted file mode 100644
index d01e92ab8e0..00000000000
--- a/etc/ACE-guidelines.html
+++ /dev/null
@@ -1,367 +0,0 @@
-<!-- $Id$ -->
-
-<html>
- <head>
- <title>ACE Implementation Guidelines</title>
- <link rev=made href="mailto:levine@cs.wustl.edu">
- </head>
-
-<body>
-<center>
- <h1>ACE Implementation Guidelines</h1>
- <font size=-1>
- Last modified <!--#echo var="LAST_MODIFIED" -->.<p>
- </font>
-</center>
-<h2>&nbsp</h2>
-
-Thanks to Graham Dumpleton &lt;grahamd@nms.otc.com.au&gt; for providing
-corrections to the OSE Classtools link and description. Thanks also
-to Graham for providing the OSE tools!<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>
- </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 /**/ &lt;synch.h&gt;
- # include /**/ &lt;thread.h&gt;
- # 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 &lt; Options::instance ()-&gt;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 &lt; Options::instance ()-&gt;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 &lt;object_addr_&gt; cache from &lt;host&gt; and &lt;port&gt;.
-
- ACE_INET_Addr &object_addr (void);
- // Returns the &lt;ACE_INET_Addr&gt; 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>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>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_hrtime_t is
- always 8 bytes. (We should/may/will add an ACE_UINT64, soon.)<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>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-&gt;count_) &gt; that-&gt;size_;
- </pre><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>
-</ul><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-&gt;name_space_, LOCAL_NAME_SPACE, -1);
-
- if (ACE_LOG_MSG-&gt;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/~schmidt/ACE-overview.html">ACE</a>
- Design Rules</h3>
-<ul>
- <li>If you are parameterizing a searchable container template class
- with readers/writer locks, do not use sentinels.<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
- before checking it into the CVS repository.<p>
-</ul><p>
-
-<hr>
-<!-- hhmts start -->
-Last modified: Mon Nov 10 18:27:08 CST 1997
-<!-- hhmts end -->
-
-</body>
-</html>