]> git.saurik.com Git - wxWidgets.git/blobdiff - docs/html/standard.htm
More makefile and project fun
[wxWidgets.git] / docs / html / standard.htm
index 61d507667eaa44249164f730501347ea6ffb3bf5..0f2b5562309562b10cdacc28cf66d4da11d8ef3a 100644 (file)
@@ -24,7 +24,7 @@ wxWindows Programmer Style Guide
 by <A HREF=mailto:zeitlin@dptmaths.ens-cachan.fr>Vadim Zeitlin</A><P>
 
 This guide is intended for people who are (or intending to start) writing code
 by <A HREF=mailto:zeitlin@dptmaths.ens-cachan.fr>Vadim Zeitlin</A><P>
 
 This guide is intended for people who are (or intending to start) writing code
-for <A HREF="http://web.ukonline.co.uk/julian.smart/wxwin/" target=_top>wxWindows</A> class library.
+for <A HREF="http://www.wxwindows.org" target=_top>wxWindows</A> class library.
 
 <P>
 The guide is separated into two parts: the first one addresses the general
 
 <P>
 The guide is separated into two parts: the first one addresses the general
@@ -35,7 +35,7 @@ its goal it to make wxWindows as uniform as possible without imposing too
 many restrictions on the programmer.
 <P>
 Acknowledgements: This guide is partly based on <A
 many restrictions on the programmer.
 <P>
 Acknowledgements: This guide is partly based on <A
-HREF=http://www.mozilla.org/docs/tplist/catBuild/portable-cpp.html target=_top>
+HREF="http://www.mozilla.org/hacking/portable-cpp.html" target=_top>
 C++ portability guide</A> by David Williams.
 
 <P>
 C++ portability guide</A> by David Williams.
 
 <P>
@@ -52,14 +52,22 @@ C++ portability guide</A> by David Williams.
     <LI><A HREF="#no_nestedclasses">Don't use nested classes</A></LI>
   </OL>
   <BR>
     <LI><A HREF="#no_nestedclasses">Don't use nested classes</A></LI>
   </OL>
   <BR>
+  <LI>Other compiler limitations</LI>
+  <OL>
+    <LI><A HREF="#no_ternarywithobjects">Use ternary operator ?: carefully</A></LI>
+    <LI><A HREF="#no_autoaggregate">Don't use initializers with automatic arrays</A></LI>
+    <LI><A HREF="#no_dtorswithoutctor">Always have at least one constructor in a class with destructor</A></LI>
+  </OL>
+  <BR>
   <LI>General recommendations</LI>
   <OL>
   <LI>General recommendations</LI>
   <OL>
+    <LI><A HREF="#no_cppcommentsinc">No C++ comments in C code></A></LI>
     <LI><A HREF="#no_globals">No global variables with constructor</A></LI>
     <LI><A HREF="#no_warnings">Turn on all warnings and eradicate them</A></LI>
     <LI><A HREF="#no_assume_sizeof">Don't rely on <TT>sizeof(int) == 2</TT>...</A></LI>
     <LI><A HREF="#no_assignment_in_if">No assignments in conditional expressions</A></LI>
     <LI><A HREF="#no_globals">No global variables with constructor</A></LI>
     <LI><A HREF="#no_warnings">Turn on all warnings and eradicate them</A></LI>
     <LI><A HREF="#no_assume_sizeof">Don't rely on <TT>sizeof(int) == 2</TT>...</A></LI>
     <LI><A HREF="#no_assignment_in_if">No assignments in conditional expressions</A></LI>
-    <LI><A HREF="#no_comment_code">Use <TT>#if 0</TT> rather than comments to temporarily
-                    disable blocks of code</A></LI>
+    <LI><A HREF="#no_comment_code">Use <TT>#if 0</TT> rather than comments to temporarily disable blocks of code</A></LI>
+    <LI><A HREF="#no_overloaded_virtuals">Avoid overloaded virtual functions</A></LI>
     <LI><A HREF="#no_extra_semicolon">Don't use extra semi-colons on top level</A></LI>
   </OL>
   <BR>
     <LI><A HREF="#no_extra_semicolon">Don't use extra semi-colons on top level</A></LI>
   </OL>
   <BR>
@@ -70,15 +78,14 @@ C++ portability guide</A> by David Williams.
     <LI><A HREF="#no_carriagereturn">Avoid carriage returns in cross-platform code</A></LI>
     <LI><A HREF="#no_caps_in_filenames">Use only lower letter filenames</A></LI>
     <LI><A HREF="#no_incomplete_files">Terminate the files with a new-line</A></LI>
     <LI><A HREF="#no_carriagereturn">Avoid carriage returns in cross-platform code</A></LI>
     <LI><A HREF="#no_caps_in_filenames">Use only lower letter filenames</A></LI>
     <LI><A HREF="#no_incomplete_files">Terminate the files with a new-line</A></LI>
+    <LI><A HREF="#no_case_only_diff">Avoid globals differing by case only</A></LI>
   </OL>
   <BR>
   <LI>Style choices</LI>
   <OL>
     <LI><A HREF="#naming_conv">Naming conventions: use <TT>m_</TT> for members</A></LI>
   </OL>
   <BR>
   <LI>Style choices</LI>
   <OL>
     <LI><A HREF="#naming_conv">Naming conventions: use <TT>m_</TT> for members</A></LI>
-    <LI><A HREF="#no_void_param">Don't use <TT>void</TT> for functions without
-                    arguments</A></LI>
-    <LI><A HREF="#no_const_int">Don't use <TT>const</TT> for non pointer/reference
-                    arguments</A></LI>
+    <LI><A HREF="#no_void_param">Don't use <TT>void</TT> for functions without arguments</A></LI>
+    <LI><A HREF="#no_const_int">Don't use <TT>const</TT> for non pointer/reference arguments</A></LI>
   </OL>
 </UL>
 
   </OL>
 </UL>
 
@@ -105,8 +112,7 @@ C++ portability guide</A> by David Williams.
   <LI>More about naming conventions</LI>
   <OL>
     <LI><A HREF="#wx_prefix">Use wx or WX prefix for all public symbols</A></LI>
   <LI>More about naming conventions</LI>
   <OL>
     <LI><A HREF="#wx_prefix">Use wx or WX prefix for all public symbols</A></LI>
-    <LI><A HREF="#wxdllexport">Use WXDLLEXPORT with all classes/functions in
-                               wxMSW/common code</A></LI>
+    <LI><A HREF="#wxdllexport">Use WXDLLEXPORT with all classes/functions in wxMSW/common code</A></LI>
     <LI><A HREF="#set_get">Use Set/Get prefixes for accessors</A></LI>
     <LI><A HREF="#constants">wxNAMING_CONSTANTS</A></LI>
   </OL>
     <LI><A HREF="#set_get">Use Set/Get prefixes for accessors</A></LI>
     <LI><A HREF="#constants">wxNAMING_CONSTANTS</A></LI>
   </OL>
@@ -332,6 +338,53 @@ you can try the following:
 <P>A nice side effect is that you don't need to recompile all the files
 including the header if you change the PrivateLibClass declaration (it's
 an example of a more general interface/implementation separation idea).
 <P>A nice side effect is that you don't need to recompile all the files
 including the header if you change the PrivateLibClass declaration (it's
 an example of a more general interface/implementation separation idea).
+</OL>
+
+  <BR>
+  <LI>Other compiler limitations</B></LI><P>
+This section lists the less obvious limitations of the current C++ compilers
+which are less restrictive than the ones mentioned in the previous section but
+are may be even more dangerous as a program which compiles perfectly well on
+some platform and seems to use only standard C++ featurs may still fail to
+compile on another platform and/or with another compiler.
+
+<OL>
+  <P><LI><A NAME="no_ternarywithobjects"></A><B>Use ternary operator ?: carefully</B></LI><P>
+  The ternary operator <TT>?:</TT> shouldn't be used with objects (i.e. if any
+of its operands are objects) because some compilers (notable Borland C++) fail
+to compile such code.
+<P><U>Workaround</U>: use <TT>if/else</TT> instead.
+<PRE>
+    wxString s1, s2;
+
+    // Borland C++ won't compile the line below
+    wxString s = s1.Len() < s2.Len() ? s1 : s2;
+
+    // but any C++ compiler will compile this
+    wxString s;
+    if ( s1.Len() < s2.Len() )
+        s = s1;
+    else
+        s = s2;
+</PRE>
+
+   <P><LI><A NAME="no_autoaggregate"></A><B>Don't use initializers with automatic arrays</B></LI><P>
+The initializers for automatic array variables are not supported by some older
+compilers. For example, the following line
+<PRE>
+    int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+</PRE>
+will fail to compile with HP-UX C++ compiler.
+<P><U>Workaround</U>: either make the array static or initialize each item
+separately: in the (stupid) example above, the array should be definitely
+declared as <TT>static const</TT> (assuming that the leap years are dealt with
+elsewhere somehow...) which is ok. When an array is really not const, you
+should initialize each element separately.
+
+   <P><LI><A NAME="no_dtorswithoutctor"></A><B>Always have at least one constructor in a class with destructor</B></LI><P>
+It is a good rule to follow in general, but some compilers (HP-UX) enforce it.
+So even if you are sure that the default constructor for your class is ok but
+it has a destructor, remember to add an empty default constructor to it.
 </OL>
 
   <BR>
 </OL>
 
   <BR>
@@ -343,6 +396,18 @@ which <B>must</B> be followed if you wish to write correct, i.e. working, progra
 also contains some C/C++ specific remarks in the end which are less
 important.
   <OL>
 also contains some C/C++ specific remarks in the end which are less
 important.
   <OL>
+    <P><LI><A NAME="no_cppcommentsinc"><B>No C++ comments in C code></B></LI><P>
+Never use C++ comments in C code - not all C compilers/preprocessors
+understand them. Although we're mainly concerned with C++ here, there are
+several files in wxWindows sources tree which are compiled with C compiler.
+Among them are <TT>include/wx/setup.h</TT> and <TT>include/wx/expr.h</TT>.
+
+Another thing related to C vs C++ preprocessor differences is that some old C
+preprocessors require that all directives start in the first column (while
+it's generally allowed to have any amount of whitespace before them in C++),
+so you should start them in the beginning of the line in files which are
+compiled with C compiler.
+
     <P><LI><A NAME="no_globals"></A><B>No global variables with constructors</B></LI><P>
 In C++, the constructors of global variables are called before the
 <TT>main()</TT> function (or <TT>WinMain()</TT> or any other program entry point)
     <P><LI><A NAME="no_globals"></A><B>No global variables with constructors</B></LI><P>
 In C++, the constructors of global variables are called before the
 <TT>main()</TT> function (or <TT>WinMain()</TT> or any other program entry point)
@@ -444,6 +509,70 @@ instead of
 The reason is simple: if there are any <TT>/* ... */</TT> comments inside
 <TT>...</TT> the second version will, of course, miserably fail.
 
 The reason is simple: if there are any <TT>/* ... */</TT> comments inside
 <TT>...</TT> the second version will, of course, miserably fail.
 
+    <P><LI><A NAME="no_overloaded_virtuals"></A><B>Avoid overloaded virtual functions</B></LI><P>
+
+You should avoid having overloaded virtual methods in a base class because if
+any of them is overriden in a derived class, then all others must be overriden
+as well or it would be impossible to call them on an object of derived class.
+
+For example, the following code:
+
+<PRE>
+    class Base
+    {
+    public:
+        virtual void Read(wxFile& file);
+        virtual void Read(const wxString& filename);
+    };
+
+    class Derived : public Base
+    {
+    public:
+        virtual void Read(wxFile& file) { ... }
+    };
+
+    ...
+
+    Derived d;
+    d.Read("some_filename");    // compile error here!
+</PRE>
+
+will fail to compile because the base class function taking <TT>filename</TT>
+is hidden by the virtual function overriden in the derived class (this is
+known as [virtual] function name hiding problem in C++).
+
+<P>
+The standard solution to this problem in wxWindows (where we have such
+situations quite often) is to make both <TT>Read()</TT> functions not virtual
+and introduce a single virtual function <TT>DoRead()</TT>. Usually, it makes
+sense because the function taking a filename is (again, usually) implemented
+in terms of the function reading from a file anyhow (but making only this
+functions not virtual won't solve the above problem!).
+<P>
+So, the above declarations should be written as:
+<PRE>
+    class Base
+    {
+    public:
+        void Read(wxFile& file);
+        void Read(const wxString& filename);
+
+    protected:
+        virtual void DoRead(wxFile& file);
+    };
+
+    class Derived : public Base
+    {
+    protected:
+        virtual void DoRead(wxFile& file) { ... }
+    };
+</PRE>
+
+This technique is widely used in many of wxWindows classes - for example,
+<TT>wxWindow</TT> has more than a dozen of <TT>DoXXX()</TT> functions which
+allows to have many overloaded versions of commonly used methods such as
+<TT>SetSize()</TT>
+
     <P><LI><A NAME="no_extra_semicolon"></A><B>Don't use extra semi-colons on top level</B></LI><P>
 Some compilers don't pay any attention to extra semicolons on top level, as in
 <PRE>
     <P><LI><A NAME="no_extra_semicolon"></A><B>Don't use extra semi-colons on top level</B></LI><P>
 Some compilers don't pay any attention to extra semicolons on top level, as in
 <PRE>
@@ -495,6 +624,13 @@ While DOS/Windows compilers don't seem to mind, their Unix counterparts don't
 like files without terminating new-line. Such files also give a warning message
 when loaded to vim (the Unix programmer's editor of choice :-)), so please think
 about terminating the last line.
 like files without terminating new-line. Such files also give a warning message
 when loaded to vim (the Unix programmer's editor of choice :-)), so please think
 about terminating the last line.
+
+    <P><LI><A NAME="no_case_only_diff"></A><B>Avoid globals differing by case only</B></LI><P>
+The linker on VMS is case-insensitive. Therefore all external variables and
+functions which differ only in case are not recognized by the linker as
+different, so all externals should differ in more than the case only:
+i.e. <TT>GetId</TT> is the same as <TT>GetID</TT>. 
+
   </OL>
 
   <BR>
   </OL>
 
   <BR>
@@ -733,12 +869,6 @@ WXDLLEXPORT_DATA(extern wxApp*) wxTheApp;
 The reason for the strange syntax for data is that some compilers use different
 keyword ordering for exporting data.
 
 The reason for the strange syntax for data is that some compilers use different
 keyword ordering for exporting data.
 
-<P>There also several other places where you should take care of shared
-library case: all IMPLEMENT_xxx macros which are usually used in the
-corresponding .cpp files must be taken inside
-"<TT>&#35;if !USE_SHARED_LIBRARY</TT>" and in the <TT>&#35;if USE_SHARED_LIBRARY</TT>
-case you should put them inside <TT>common/cmndata.cpp</TT> file.
-
     <P><LI><A NAME="set_get"></LI><B>Use Set/Get prefixes for accessors</B><P>
 There is a convention in wxWindows to prefix the accessors (i.e. any simple, in
 general, inline function which does nothing else except changing or returning
     <P><LI><A NAME="set_get"></LI><B>Use Set/Get prefixes for accessors</B><P>
 There is a convention in wxWindows to prefix the accessors (i.e. any simple, in
 general, inline function which does nothing else except changing or returning