3 <TITLE>Dali C++ Coding Conventions</TITLE>
5 green code for good examples, same formatting as <pre> tag
6 red code for bad examples, same formatting as <pre> tag
7 details hidden by default
9 <style type="text/css">
10 code.good { color:green; white-space:pre; }
11 code.bad { color:red; white-space:pre; }
12 article.detail { display:block; }
15 <script type="text/javascript">
16 function toggleVisibility( button, obj )
18 // must have button and object
21 var e=document.getElementById( obj );
25 // initially display property seems to be empty, then none
26 if( e.style.display == "" || e.style.display == "none" )
30 e.style.display="block";
36 e.style.display="none";
46 Here's a few pragmatic programmer guidelines to follow (<A HREF="http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm">Web version</A>)
47 <H3>Details <input type="button" value="Hide" onclick="toggleVisibility( this, 'general_details' );"/></H3>
48 <ARTICLE class="detail" id="general_details">
50 <LI><B>Care About the Software, Care about your API users and end users</B><BR>
51 Why spend your life developing software unless you care about doing it well?
52 Turn off the autopilot and take control. Constantly critique and appraise your work.
53 <LI><B>Don't Live with Broken Windows</B><BR>
54 Fix bad designs, wrong decisions, and poor code when you see them.
55 You can't force change on people. Instead, show them how the future might be and help them participate in creating it.
56 <LI><B>Remember the Big Picture</B><BR>
57 Don't get so engrossed in the details that you forget to check what's happening around you.
58 <LI><B>DRY - Don't Repeat Yourself</B><BR>
59 Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
60 <LI><B>Eliminate Effects Between Unrelated Things</B><BR>
61 Design components that are self-contained. independent, and have a single, well-defined purpose.
62 <LI><B>There Are No Final Decisions</B><BR>
63 No decision is cast in stone. Instead, consider each as being written in the sand at the beach, and plan for change.
64 <LI><B>Fix the Problem, Not the Blame</B><BR>
65 It doesn't really matter whether the bug is your fault or someone else's—it is still your problem, and it still needs to be fixed.
66 <LI><B>You Can't Write Perfect Software</B><BR>
67 Software can't be perfect. Protect your code and users from the inevitable errors.
68 <LI><B>Design with Contracts</B><BR>
69 Use contracts to document and verify that code does no more and no less than it claims to do.
70 <LI><B>Crash Early</B><BR>
71 A dead program normally does a lot less damage than a crippled one.
72 <LI><B>Use Assertions to Prevent the Impossible</B><BR>
73 Assertions validate your assumptions. Use them to protect your code from an uncertain world.
74 <LI><B>Use Exceptions for Exceptional Problems</B><BR>
75 Exceptions can suffer from all the readability and maintainability problems of classic spaghetti code. Reserve exceptions for exceptional things.
76 <LI><B>Minimize Coupling Between Modules</B><BR>
77 Avoid coupling by writing "shy" code and applying the Law of Demeter.
78 <LI><B>Put Abstractions in Code, Details in Metadata</B><BR>
79 Program for the general case, and put the specifics outside the compiled code base.
80 <LI><B>Always Design for Concurrency</B><BR>
81 Allow for concurrency, and you'll design cleaner interfaces with fewer assumptions.
82 <LI><B>Don't Program by Coincidence</B><BR>
83 Rely only on reliable things. Beware of accidental complexity, and don't confuse a happy coincidence with a purposeful plan.
84 <LI><B>Test Your Estimates</B><BR>
85 Mathematical analysis of algorithms doesn't tell you everything. Try timing your code in its target environment.
86 <LI><B>Refactor Early, Refactor Often</B><BR>
87 Just as you might weed and rearrange a garden, rewrite, rework, and re-architect code when it needs it. Fix the root of the problem.
88 <LI><B>Design to Test</B><BR>
89 Start thinking about testing before you write a line of code.
90 <LI><B>Abstractions Live Longer than Details</B><BR>
91 Invest in the abstraction, not the implementation. Abstractions can survive the barrage of changes from different implementations and new technologies.
92 <LI><B>Coding Ain't Done 'Til All the Tests Run</B><BR>
94 <LI><B>Use Saboteurs to Test Your Testing</B><BR>
95 Introduce bugs on purpose in a separate copy of the source to verify that testing will catch them.
96 <LI><B>Find Bugs Once</B><BR>
97 Once a human tester finds a bug, it should be the last time a human tester finds that bug. Automatic tests should check for it from then on.
98 <LI><B>Sign Your Work</B><BR>
99 Craftsmen of an earlier age were proud to sign their work. You should be, too.
104 <H2>Avoid Tight Coupling</H2>
106 Always choose the loosest possible coupling between entities. In C++ the tightest coupling is Friend, second is Inheritance,
107 then Containment and last is Usage through reference, pointer or handle.
108 <H3>Details <input type="button" value="Hide" onclick="toggleVisibility( this, 'coupling_details' );"/></H3>
109 <ARTICLE class="detail" id="coupling_details">
111 <LI>Friend defines a "must-know" about details of implementation, don't use it unless your happy stating that Xxx really <B>must</B> know about Yyy implementation. and Yyy can never change without informing Xxx.
112 <LI>Inheritance defines a "is-a" relationship, don't use it unless you really can naturally say Xxx is-a Yyy. Most of the cases containment through interface is what you
113 <LI>Containment defines a "owns-a" relationship, use it when you have a natural Xxx owns-a Yyy relationship.
115 Most of the time containment through interface and normal usage is what you should go for.
116 Strong ownership always beats sharing through reference counting. Reference counting means "part owns".
117 You would not want to part own anything in real life, so why do that in software? sooner or later it will leak,
121 Two key principles to follow:
122 <H2>Open Closed Principle</H2>
124 Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
125 That is, such an entity can allow its behaviour to be modified without altering its source code. Techniqu
128 <H2>Dependency Inversion Principle</H2>
130 High-level modules should not depend on low-level modules. Both should depend on abstractions.
131 Abstractions should not depend upon details. Details should depend upon abstractions.
134 <H1>General conventions</H1>
135 <H2>Type casting <input type="button" value="Hide" onclick="toggleVisibility( this, 'ccasts_details' );"/></H2>
136 <ARTICLE class="detail" id="ccasts_details">
138 <B>Never use C-Style Casts</B><BR>
139 The C-style cast - "(type) expr" used to convert one fundamental type to another is subject to implementation-defined effects.
140 For scalar types it can result in silent truncation of the value. For pointers and references, it does not check the
141 compatibility of the value with the target type.<BR>
142 <B>Don't cast away const, use mutable keyword instead</B><BR>
143 <B>Don't reinterpret_cast, fix the design instead</B><BR>
144 <B>Remember that reference cast will throw an error if cast fails</B><BR>
145 <B>Avoid using pointer or reference casts. They have been referred to as the goto of OO programming, fix the design instead</B><BR>
148 X* ptr = static_cast<X*>( y_ptr ); // ok, compiler checks whether types are compatible
151 (Foo*) ptr; // bad! C-cast is not guaranteed to check and never complains
157 A class interface should be complete and minimal. Class should encapsulate one thing and one thing only.
158 A complete interface allows clients to do anything they may reasonably want to do.
159 On the other hand, a minimal interface will contain as few functions as possible.
160 Class methods must be defined in the same order as they are declared. This helps navigating through code.
162 <H2>Compulsory member functions <input type="button" value="Hide" onclick="toggleVisibility( this, 'implicit_method_details' );"/></H2>
163 <ARTICLE class="detail" id="implicit_method_details">
165 Every class must define default constructor, copy constructor, assignment operator and destructor.
166 If you dont declare them, compiler will and the compiler generated versions are usually not good or safe enough.
167 If your class does not support copying, then declare copy constructor and assignment operator as private and don't define them.
170 If for example the assignment operator is not needed for a particular class, then it
171 must be declared private and not defined. Any attempt to invoke the operator will result
172 in a compile-time error. On the contrary, if the assignment operator is not declared, then
173 when it is invoked, a compiler-generated form will be created and subsequently executed.
174 This could lead to unexpected results. The same goes with default constructor and copy constructor.
179 X(); // default constructor
180 X( const X& ); // copy constructor
181 X& operator=( const X& ); // copy assignment operator
186 <H2>Class types <input type="button" value="Hide" onclick="toggleVisibility( this, 'class_types_details' );"/></H2>
187 <ARTICLE class="detail" id="class_types_details">
189 Classes can have either <B>Value</B> semantics or <B>Pointer</B> semantics. Not both.
190 It must be clearly documented whether a class follows value or pointer semantics and this also
191 sets requirements on the class interface.
194 Classes with <B>Value</B> semantics are passed as value types. These classes provide a copy constructor,
195 a default constructor and assignment operator so that they can be copied and also stored on STL containers.
198 Classes with <B>Pointer</B> semantics are always passed through pointers, references or smart pointers.
199 These classes are ususally compound types that cannot be easily copied and thus prevent copy constructor,
200 and assignment operator. That can be only stored on STL containers through smart pointers.
203 <H2>Access Rights <input type="button" value="Hide" onclick="toggleVisibility( this, 'access_details' );"/></H2>
204 <ARTICLE class="detail" id="access_details">
206 Public and protected data should only be used in structs, not classes.
207 Roughly two types of classes exist: those that essentially aggregate data and those that provide
208 an abstraction while maintaining a well-defined state or invariant.
211 A structure should be used to model an entity that does not require an invariant (Plain Old Data)
212 A class should be used to model an entity that maintains an invariant.
213 <B>Rationale:</B> A class is able to maintain its invariant by controlling access to its data. However,
214 a class cannot control access to its members if those members non-private.
215 Hence all data in a class should be private.
218 <H2>Constructors <input type="button" value="Hide" onclick="toggleVisibility( this, 'constructor_details' );"/></H2>
219 <ARTICLE class="detail" id="constructor_details">
221 Virtual function calls are not allowed from constructor
222 Rationale: Virtual functions are resolved statically (not dynamically) in constructor
225 Member initialization order must be the same in which they are declared in the class.
226 Note: Since base class members are initialized before derived class members, base class
227 initializers should appear at the beginning of the member initialization list.
228 <B>Rationale:</B> Members of a class are initialized in the order in which they are declared—not
229 the order in which they appear in the initialization list.
232 Constructor body should not throw an exception, keep constructor simple and trivial.
233 If constructor fails, objects lifecycle never started, destructor will not be called.
236 Declare all single argument constructors as explicit thus preventing their use as implicit type convertors.
241 explicit C( int ); // good, explicit
242 C( int, int ); // ok more than one non-default argument
249 C( double ); // bad, can be used in implicit conversion
250 C( float f, int i=0 ); // bad, implicit conversion constructor
251 C( int i=0, float f=0.0 ); // bad, default constructor, but also a conversion constructor
256 <H2>Destructor <input type="button" value="Hide" onclick="toggleVisibility( this, 'destructor_details' );"/></H2>
257 <ARTICLE class="detail" id="destructor_details">
259 All classes should define a destructor, either:
261 <LI>public for value types
262 <LI>public and virtual for base classes with virtual methods
263 <LI>protected and virtual for base classes to prevent deletion (and ownership) through base class
265 This prevents undefined behavior. If an application attempts to delete a derived class object
266 through a base class pointer, the result is undefined if the base class destructor is non-virtual.
269 Virtual function calls are not allowed from inside the destructor.
270 Rationale: A class's virtual functions are resolved statically (not dynamically) in its destructor
273 All resources acquired by a class shall be released by the class's destructor.
276 Destructor is not allowed to throw an exception, avoid doing complicated things in destructor.
279 <H2>Methods <input type="button" value="Hide" onclick="toggleVisibility( this, 'method_details' );"/></H2>
280 <ARTICLE class="detail" id="method_details">
282 Don't shortcut, like use the returned reference of getter to assign a new value. If a Setter is missing, add it!
284 initial.GetPosition() = Position(10, 10); // bad!, If GetPosition is one day changed to return copy
285 // of Position this code silently changes to a no-op.
288 initial.SetPosition( Position( 10, 10 ) );
292 Code that is not used (commented out) should be deleted.
293 Rationale: No dead code should be left to confuse other people.
294 Exception: Code that is simply part of an explanation may appear in comments.
300 <H2>Inline member functions <input type="button" value="Hide" onclick="toggleVisibility( this, 'inline_details' );"/></H2>
301 <ARTICLE class="detail" id="inline_details">
304 GCC automatically inlines member functions defined within the class body of C++ programs even if they are not explicitly declared inline.
308 inline float& GetRed() { return mRed; } // inline keyword not needed
309 inline float& GetGreen(){ return mGreen; }
315 float& GetRed() { return mRed; }
316 float& GetGreen(){ return mGreen; }
321 If there are a lot of inlines, they should be in a .inl file.
322 Remember the inline keyword is just a hint to the compiler. Whether
323 a function will be inlined or not is down to the compiler and its flags.
329 <P>Thats all folks, if you read this far you are now all equipped to write good code :) !! </P>