git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7748 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			954 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			954 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <HTML>
 | |
| <HEAD>
 | |
|   <TITLE>wxWindows Programmer Style Guide</TITLE>
 | |
| </HEAD>
 | |
| 
 | |
| <BODY>
 | |
| 
 | |
| <a name="top"></a>
 | |
| 
 | |
| <font face="Arial, Lucida Sans, Helvetica">
 | |
| 
 | |
| <table width=100% border=0 cellpadding=5 cellspacing=0>
 | |
| <tr>
 | |
| <td bgcolor="#C4ECF9">
 | |
| <font size=+1 face="Arial, Lucida Sans, Helvetica" color="#000000">
 | |
| wxWindows Programmer Style Guide
 | |
| </font>
 | |
| </td>
 | |
| </tr>
 | |
| </table>
 | |
| 
 | |
| <P>
 | |
| 
 | |
| 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://www.wxwindows.org" target=_top>wxWindows</A> class library.
 | |
| 
 | |
| <P>
 | |
| The guide is separated into two parts: the first one addresses the general
 | |
| compatibility issues and is not wxWindows-specific. The advises in this part
 | |
| will hopefully help you to write programs which compile and run on greater
 | |
| variety of platforms. The second part details the wxWindows code organization and
 | |
| 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
 | |
| HREF="http://www.mozilla.org/hacking/portable-cpp.html" target=_top>
 | |
| C++ portability guide</A> by David Williams.
 | |
| 
 | |
| <P>
 | |
| <H3>General C++ Rules</H3>
 | |
| <UL>
 | |
|   <LI>New or not widely supported C++ features</LI>
 | |
|   <OL>
 | |
|     <LI><A HREF="#no_templates">Don't use C++ templates</A></LI>
 | |
|     <LI><A HREF="#no_exceptions">Don't use C++ exceptions</A></LI>
 | |
|     <LI><A HREF="#no_rtti">Don't use RTTI</A></LI>
 | |
|     <LI><A HREF="#no_namespaces">Don't use namespaces</A></LI>
 | |
|     <LI><A HREF="#no_stl">Don't use STL</A></LI>
 | |
|     <LI><A HREF="#no_fordecl">Don't declare variables inside <TT>for()</TT></A></LI>
 | |
|     <LI><A HREF="#no_nestedclasses">Don't use nested classes</A></LI>
 | |
|     <LI><A HREF="#no_newlogicalops">Don't use new logical operators keywords</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><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_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>Unix/DOS differences</LI>
 | |
|   <OL>
 | |
|     <LI><A HREF="#use_cpp_ext">Use .cpp for C++ source file extension</A></LI>
 | |
|     <LI><A HREF="#no_backslash">Don't use backslash ('\\') in #includes</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>
 | |
|     <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>
 | |
| 
 | |
| <P>
 | |
| 
 | |
| <H3>wxWindows Rules</H3>
 | |
| <UL>
 | |
|   <LI>Files location and naming conventions</LI>
 | |
|   <OL>
 | |
|     <LI><A HREF="#file_locations">File locations</A></LI>
 | |
|     <LI><A HREF="#include_guards">Include guards</A></LI>
 | |
|     <LI><A HREF="#pch">Precompiled headers</A></LI>
 | |
|   </OL>
 | |
| 
 | |
|   <BR>
 | |
|   <LI>File layout and indentation</LI>
 | |
|   <OL>
 | |
|     <LI><A HREF="#wxwin_header">wxWindows standard header</A></LI>
 | |
|     <LI><A HREF="#indentation">Indent your code with 4 spaces (no tabs!)</A></LI>
 | |
|     <LI><A HREF="#class_decl">Order of parts in a class declarations</A></LI>
 | |
|   </OL>
 | |
| 
 | |
|   <BR>
 | |
|   <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="#set_get">Use Set/Get prefixes for accessors</A></LI>
 | |
|     <LI><A HREF="#constants">wxNAMING_CONSTANTS</A></LI>
 | |
|   </OL>
 | |
| 
 | |
|   <BR>
 | |
|   <LI>Miscellaneous</LI>
 | |
|   <OL>
 | |
|     <LI><A HREF="#forward_decl">Use forward declarations whenever possible</A></LI>
 | |
|     <LI><A HREF="#debug_macros">Use debugging macros</A></LI>
 | |
|   </OL>
 | |
| </UL>
 | |
| 
 | |
| <HR>
 | |
| 
 | |
| <H3>General C++ Rules</H3>
 | |
| <UL>
 | |
|   <LI>New or not widely supported C++ features</LI>
 | |
| 
 | |
|   <P>The usage of all features in this section is not recommended for one reason: they appeared in C++ relatively recently and are not yet
 | |
| supported by all compilers. Moreover, when they're supported, there are
 | |
| differences between different vendor's implementations. It's understandable that
 | |
| you might love one (or all) of these features, but you surely can write C++
 | |
| programs without them. Where possible, workarounds to compensate for absence
 | |
| of your favourite C++ abilities are indicated.
 | |
|   <P>Just to suppress any doubts that there are compilers which don't support
 | |
| these new features, you can think about Win16 (a.k.a. Win 3.1) compilers,
 | |
| <I>none</I> of which supports <I>any</I> feature from the list below.
 | |
| 
 | |
|   <OL>
 | |
|     <P><LI><A NAME="no_templates"></A><B>Don't use C++ templates</B></LI><P>
 | |
| Besides the reasons mentioned above, template usage also makes the
 | |
| program compile much slower (200%-300% is not uncommon) and their support
 | |
| even in the compilers which have had it for a long time is far from perfect
 | |
| (the best example is probably gcc).
 | |
| <P><U>Workaround</U>: The things you would like to use templates for are,
 | |
| most commonly, polymorphic containers (in the sense that they can contain objects of
 | |
| any type without compromising C++ type system, i.e. using <TT>void *</TT>
 | |
| is out of question). wxWindows provides <A HREF="TODO">dynamic
 | |
| arrays and lists</A> which are sufficient in 99% of cases - please don't hesitate
 | |
| to use them. Lack of template is not a reason to use static arrays or
 | |
| type-less (passing by <TT>void *</TT>) containers.
 | |
| 
 | |
|     <P><LI><A NAME="no_exceptions"></A><B>Don't use C++ exceptions</B></LI><P>
 | |
| The C++ exception system is an error-reporting mechanism. Another reasons not to use it,
 | |
| besides portability, are the performance penalty it imposes (small, but, at least for
 | |
| current compilers, non-zero), and subtle problems with
 | |
| memory/resource deallocation it may create (the place where you'd like to use
 | |
| C++ exceptions most of all are the constructors, but you need to be very
 | |
| careful in order to be able to do it).
 | |
| <P><U>Workaround</U>: there is no real workaround, of course, or the exceptions
 | |
| wouldn't have been added to the language. However, there are several rules which
 | |
| might help here:<P>
 | |
| 
 | |
| <OL>
 | |
|   <LI>Every function returns an integer (or at least boolean) error code.
 | |
|       <P>There is no such thing as a function that never fails - even if it can't
 | |
|       fail now, it might do it later, when modified to be more powerful/general.
 | |
|       Put the <TT>int</TT> or <TT>bool</TT> return type from the very beginning!<P>
 | |
|   </LI><LI>Every function you call may fail - check the return code!
 | |
|       <P>Never rely on the function's success, always test for a possible error.<P>
 | |
|   </LI><LI>Tell the user about the error, don't silently ignore them.
 | |
|       <P>Exceptions are always caught and, normally, processed when they're
 | |
|       caught. In the same manner, the error return code must always be processed
 | |
|       somehow. You may choose to ignore it, but at least tell the user that
 | |
|       something wrong happened using <A HREF="TODO"><TT>wxLogError</TT></A> or
 | |
|       <A HREF="TODO"><TT>wxLogWarning</TT></A> functions. All wxWindows
 | |
|       functions (must) log the error messages on failure - this can be disabled
 | |
|       by using <A HREF="TODO">wxLogNull</A> object before calling it.
 | |
|       <P>Examples:<UL>
 | |
|         <LI><I>Wrong</I>:
 | |
|         <PRE>
 | |
| void ReadAddressBookFile(const wxString& strName)
 | |
| {
 | |
|   wxFile file;
 | |
| 
 | |
|   if ( !file.Open(strFile) )
 | |
|     return;
 | |
| 
 | |
|   ...process it...
 | |
| }
 | |
|         </PRE>
 | |
|         </LI><LI><I>Correct</I>:
 | |
|         <PRE>
 | |
| // returns false if the address book couldn't be read
 | |
| bool ReadAddressBookFile(const wxString& strName)
 | |
| {
 | |
|   wxFile file;
 | |
| 
 | |
|   if ( !file.Open(strFile) ) {
 | |
|     // wxFile logged an error because file couldn't be opened which
 | |
|     // contains the system error code, however it doesn't know what
 | |
|     // this file is for and an error message "can't open $GLCW.ADB"
 | |
|     // can be quite confusing for the user. Here we say what we mean.
 | |
|     wxLogError("Can't read address book from '%s'!",
 | |
| 	       strName.c_str());
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   ...process it...
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 	</PRE>
 | |
|         or, if it's not an error if file doesn't exist (here we could just check
 | |
|         its existence, but let's suppose that there is no <TT>wxFile::Exists()</TT>)
 | |
|         we can also write:
 | |
|         <PRE>
 | |
| // returns false if address book file doesn't exist
 | |
| bool ReadAddressBookFile(const wxString& strName)
 | |
| {
 | |
|   wxFile file;
 | |
| 
 | |
|   // start a block inside which all log messages are suppressed
 | |
|   {
 | |
|     wxLogNull noLog;
 | |
|     if ( !file.Open(strFile) )
 | |
|       return false;
 | |
|   }
 | |
| 
 | |
|   ...process it...
 | |
| 
 | |
|   return true;
 | |
| }
 | |
|         </PRE></LI>
 | |
|     </UL>
 | |
|   </OL>
 | |
| 
 | |
|     <P><LI><A NAME="no_rtti"></A><B>Don't use RTTI</B></LI><P>
 | |
| RTTI stands for Run-Time Type Information and there is probably no other
 | |
| reason not to use it except the portability issue and the fact that it adds
 | |
| <TT>sizeof(void *)</TT> bytes to any class having virtual functions (at least,
 | |
| in the implementations I'm aware of).
 | |
| <P><U>Workaround</U>: use wxWindows RTTI system which allows you to do almost
 | |
| everything which the new C++ RTTI, except that, of course, you have to use
 | |
| macros instead of the (horrible looking, BTW) <TT>dynamic_cast</TT>.
 | |
| 
 | |
|     <P><LI><A NAME="no_namespaces"></A><B>Don't use namespaces</B></LI><P>
 | |
| This topic is subject to change with time, however for the moment all wxWindows
 | |
| classes/functions live in the global namespace.
 | |
| <P><U>Workaround</U>: None.
 | |
| 
 | |
|     <P><LI><A NAME="no_stl"></A><B>Don't use STL</B></LI><P>
 | |
| STL is the new C++ standard library, proposing all kinds of template containers
 | |
| and generic algorithm implementations. Templates are the heart (and almost
 | |
| everything else) of the library, so its usage is out of question. Besides, even
 | |
| with the compilers which do support templates, STL has many of its own problems,
 | |
| there are many "not 100% standard compatible" vendor implementations, none of existing debuggers understands its
 | |
| complicated data structures, ... the list can go on (almost) forever.
 | |
| <P><U>Workaround</U>: Use wxString, dynamic arrays and lists and other wxWindows
 | |
| classes. wxString has many of the most often used functions of std::string STL
 | |
| class (typedef to be precise).
 | |
|     <P><LI><A NAME="no_fordecl"></A><B>Don't declare variables inside <TT>for()
 | |
|                                        </TT></B></LI><P>
 | |
| The scope of a variable declared inside <TT>for()</TT> statement changed several
 | |
| years ago, however many compilers still will complain about second declaration
 | |
| of <TT>i</TT> in the following code:
 | |
| <PRE>
 | |
|   for ( int i = 0; i < 10; i++ ) {
 | |
|     ...
 | |
|   }
 | |
| 
 | |
|   ...
 | |
| 
 | |
|   for ( int i = 0; i < 10; i++ ) {
 | |
|     ...
 | |
|   }
 | |
| </PRE>
 | |
| even though if it's perfectly legal now.
 | |
| <P><U>Workaround</U>: write this instead:
 | |
| <PRE>
 | |
|   int i;
 | |
|   for ( i = 0; i < 10; i++ ) {
 | |
|     ...
 | |
|   }
 | |
| 
 | |
|   ...
 | |
| 
 | |
|   for ( i = 0; i < 10; i++ ) {
 | |
|     ...
 | |
|   }
 | |
| </PRE>
 | |
| or, even better, use different names for the variables in the different for
 | |
| loops (in particular, avoid mute variable names like <tt>i<tt> above) - then
 | |
| you can declare them in the loop statement and don't pollute the outer name
 | |
| space with local loop variables.
 | |
| 
 | |
|   <P><LI><A NAME="no_nestedclasses"></A><B>Don't use nested classes</B></LI><P>
 | |
| Nested classes are, without doubt, a very good thing because they allow to hide
 | |
| "private" (in the sense that they're used only inside the library) classes and,
 | |
| generally, put the related things together.
 | |
| <P>Unfortunately, some compilers have trouble understanding them, so we must
 | |
| sacrifice the ideals of software design to get a working program in this case.
 | |
| <P><U>Workaround</U>: instead of
 | |
| <PRE>
 | |
|   // in the header
 | |
|   class PublicLibClass {
 | |
|   ...
 | |
|   private:
 | |
|     class PrivateLibClass { ... } m_object;
 | |
|   };
 | |
| </PRE>
 | |
| you can try the following:
 | |
| <PRE>
 | |
|   // in the header
 | |
|   class PrivateLibClass; // fwd decl
 | |
|   class PublicLibClass {
 | |
|   ...
 | |
|   private:
 | |
|    class PrivateLibClass *m_pObject;
 | |
|   };
 | |
| 
 | |
|   // in the .cpp file
 | |
|   class PrivateLibClass { ... };
 | |
| 
 | |
|   PublicLibClass::PublicLibClass()
 | |
|   {
 | |
|     m_pObject = new PrivateLibClass;
 | |
| 
 | |
|     ...
 | |
|   }
 | |
| 
 | |
|   PublicLibClass::~PublicLibClass()
 | |
|   {
 | |
|     delete m_pObject;
 | |
|   }
 | |
| </PRE>
 | |
| <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><LI><A NAME="no_newlogicalops"></A><B>Don't use new logical operators keywords</B></LI><P>
 | |
| The C++ standard has introduced the following new reserved words: <tt>or</tt>,
 | |
| <tt>and</tt>, <tt>not</tt>, <tt>xor</tt>, <tt>bitand</tt>, <tt>bitor</tt>,
 | |
| <tt>compl</tt>, <tt>and_eq</tt>, <tt>or_eq</tt>, <tt>not_eq</tt>,
 | |
| <tt>or_eq</tt> which can be used instead of the usual C operations &&,
 | |
| ||, ~ etc.
 | |
| <P>This wonderful (and not backwards compatible in addition to being
 | |
| absolutely useless) new feature means that these new keywords should not be
 | |
| used as the variable names - even if current compilers usually will accept
 | |
| this, your code will break in the future. For most of the keywords, using them
 | |
| as variable names is quite unlikely, but <tt>or</tt> and <tt>compl</tt> were
 | |
| used in the wxWindows sources which seems to indicate that they are the most
 | |
| likely candidates.
 | |
| <P>It goes without saying that these new keywords should not be used instead
 | |
| of the tradional C operators neither both because most compilers don't accept
 | |
| them and because using them in C code makes it less readable.
 | |
| </OL>
 | |
| 
 | |
|   <BR>
 | |
|   <LI>Other compiler limitations</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 (notably 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>
 | |
|   <LI>General recommendations</LI><P>
 | |
| While the recommendations in the previous section may not apply to you if you're
 | |
| only working with perfect compilers which implement the very newest directives of
 | |
| C++ standard, this section contains compiler- (and language-) independent advice
 | |
| which <B>must</B> be followed if you wish to write correct, i.e. working, programs. It
 | |
| 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)
 | |
| starts executing. Thus, there is no possibility to initialize <I>anything</I>
 | |
| before the constructor call. The order of construction is largely
 | |
| implementation-defined, meaning that there is no guarantee that one global
 | |
| object will be initialized before another one (except if they are both defined
 | |
| in the same translation unit, i.e. .cpp file). Most importantly, no custom
 | |
| memory allocation operators are installed at the moment of execution of global
 | |
| variables constructors, so a (less restrictive) rule is that you should have
 | |
| no global variables which allocate memory (or do anything else non-trivial) in
 | |
| the constructor. Of course, if an object doesn't allocate memory in its constructor
 | |
| right now, it may start making it later, so you can only be sure about this if
 | |
| you don't use <I>any</I> variables of object (as opposed to simple:
 | |
| <TT>int</TT>, ...) types. Example: currently, wxString doesn't allocate memory
 | |
| in its default constructor, so you might think that having a global (initially)
 | |
| empty wxString is safe. However, if wxString starts allocating some minimal
 | |
| amount of memory in its default constructor (which doesn't look unreasonable),
 | |
| you would have all kinds of problems with <TT>new</TT>
 | |
| and <TT>delete</TT> operators (overloaded in wxWindows), especially because the first <TT>new</TT> called
 | |
| is the standard one (before wxWindows overloads them) and <TT>delete</TT> will
 | |
| be the overloaded operator.
 | |
| 
 | |
|     <P><LI><A NAME="no_warnings"></A><B>Turn on all warnings and eradicate them</B></LI><P>
 | |
| Give the compiler a chance to help you - turn on all warnings! You should always
 | |
| use the maximum available warning level of your compiler and understand and
 | |
| correct each of them. If, for whatever reasons, a compiler gives a warning on
 | |
| some perfectly legal line of code and you can't change it, please insert a
 | |
| comment indicating it in the code. Most oftenly, however, all compiler warnings
 | |
| may be avoided (not suppressed!) with minimal changes to your code.
 | |
| 
 | |
|     <P><LI><A NAME="no_assume_sizeof"></A><B>Don't rely on <TT>sizeof(int) == 2</TT>...</B></LI><P>
 | |
| You should never assume any absolute constraints on data type sizes. Currently,
 | |
| we have 16-bit, 32-bit and 64-bit machines and even inside each class data type
 | |
| sizes are different. A small table illustrates it quite well:
 | |
| <TABLE BORDER COLS=5 WIDTH="100%" NOSAVE >
 | |
| <TR>
 | |
|   <TD>Architecture/OS</TD>
 | |
|   <TD>sizeof(short)</TD>
 | |
|   <TD>sizeof(int)</TD>
 | |
|   <TD>sizeof(long)</TD>
 | |
|   <TD>sizeof(void *)</TD>
 | |
| </TR>
 | |
| 
 | |
| <TR>
 | |
|   <TD>i386/Windows 3.1</TD>
 | |
|   <TD>2</TD>
 | |
|   <TD>2</TD>
 | |
|   <TD>4</TD>
 | |
|   <TD>2 or 4</TD>
 | |
| </TR>
 | |
| 
 | |
| <TR>
 | |
|   <TD>i386/Windows 95</TD>
 | |
|   <TD>2</TD>
 | |
|   <TD>4</TD>
 | |
|   <TD>4</TD>
 | |
|   <TD>4</TD>
 | |
| </TR>
 | |
| 
 | |
| <TR>
 | |
|   <TD>Merced/Win64</TD>
 | |
|   <TD>2</TD>
 | |
|   <TD>4</TD>
 | |
|   <TD>4</TD>
 | |
|   <TD>8</TD>
 | |
| </TR>
 | |
| 
 | |
| <TR>
 | |
|   <TD>Alpha/Linux</TD>
 | |
|   <TD>???</TD>
 | |
|   <TD>???</TD>
 | |
|   <TD>???</TD>
 | |
|   <TD>???</TD>
 | |
| </TR>
 | |
| </TABLE>
 | |
| 
 | |
|     <P><LI><A NAME="no_assignment_in_if"></A><B>No assignments in conditional expressions</B></LI><P>
 | |
| Although close to the heart of many C programmers (I plead guilty), code like
 | |
| classical <TT>if ( (c = getchar()) != EOF )</TT> is bad because it prevents you
 | |
| from enabling "assignment in conditional expression" warning (see also
 | |
| <A HREF="#no_warnings">above</A>) which is helpful to detect common
 | |
| mistypes like <TT>if ( x = 2 )</TT> instead of <TT>if ( x == 2 )</TT>.
 | |
| 
 | |
|     <P><LI><A NAME="no_comment_code"></A><B>Use <TT>#if 0</TT> rather than comments to temporarily
 | |
|                     disable blocks of code</B></LI><P>
 | |
| If you have to temporarily disable some code, use
 | |
| <PRE>
 | |
|   #if 0 // VZ: I think this code is unneeded, it probably must be removed
 | |
|     ...
 | |
|   #endif // 0
 | |
| </PRE>
 | |
| instead of
 | |
| <PRE>
 | |
|   /*
 | |
|     ...
 | |
|   */
 | |
| </PRE>
 | |
| 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>
 | |
|   class Foo { };;
 | |
| </PRE>
 | |
| while others complain loudly about it. Of course, you would rarely put 2
 | |
| semicolons yourself, but it may happen if you're using a macro
 | |
| (<TT>IMPLEMENT_something</TT>, for example) which already has a ';' inside and
 | |
| put another one after it.
 | |
|   </OL>
 | |
| 
 | |
|   <BR>
 | |
|   <LI>Unix/DOS differences</LI><P>
 | |
|   Two operating systems supported by wxWindows right now are (different flavours
 | |
| of) Unix and Windows 3.1/95/NT (although Mac, OS/2 and other ports exist/are
 | |
| being developed as well). The main differences between them are summarized
 | |
| here.
 | |
| 
 | |
|   <OL>
 | |
|     <P><LI><A NAME="use_cpp_ext"></A><B>Use .cpp for C++ source file extension</B></LI><P>
 | |
| There is, unfortunately, no standard exceptions for C++ source files. Different
 | |
| people use .C, .cc, .cpp, .cxx, .c++ and probably several others I forgot. Some
 | |
| compilers don't care about extension, but there are also other ones which can't
 | |
| be made to compile any file with "wrong" extension. Such compilers are very
 | |
| common in DOS/Windows land, that's why the .cpp extension is the least likely to
 | |
| cause any problems - it's the standard one under DOS and will probably be
 | |
| accepted by any Unix compiler as well (any counter examples?). The extension
 | |
| for the header files is .h.
 | |
| 
 | |
|     <P><LI><A NAME="no_backslash"></A><B>Don't use backslash ('\\') in #includes</B></LI><P>
 | |
| Although it's too silly to mention, please don't use backslashes in
 | |
| <TT>#include</TT> preprocessor statement. Even not all Windows compilers accept
 | |
| it, without speaking about all other ones.
 | |
| 
 | |
|     <P><LI><A NAME="no_carriagereturn"></A><B>Avoid carriage returns in cross-platform code</B></LI><P>
 | |
| This problem will hopefully not arise at all, with CVS taking care of this
 | |
| stuff, however it's perhaps not useless to remember that many Unix compilers
 | |
| (including, but not limited to, gcc) don't accept carriage returns
 | |
| (= <Ctrl-M> = '\r') in C/C++ code.
 | |
| 
 | |
|     <P><LI><A NAME="no_caps_in_filenames"></A><B>Use only lower case filenames</B></LI><P>
 | |
| DOS/Windows 3.1 isn't case sensitive, Windows 95/NT are case preserving, but not
 | |
| case sensitive. To avoid all kinds of problems with compiling under Unix (or
 | |
| any other fully case-sensitive OS), please use only lower case letters in the
 | |
| filenames.
 | |
| 
 | |
|     <P><LI><A NAME="no_incomplete_files"></A><B>Terminate the files with a new-line</B></LI><P>
 | |
| 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.
 | |
| 
 | |
|     <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>
 | |
|   <LI>Style choices</LI><P>
 | |
|   All wxWindows specific style guidelines are specified in the next
 | |
| section, here are the choices which are not completely arbitrary,
 | |
| but have some deeper and not wxWindows-specific meaning.
 | |
| 
 | |
|   <OL>
 | |
|     <P><LI><A NAME="naming_conv"></A><B>Naming conventions: use <TT>m_</TT> for members</B></LI><P>
 | |
| We all know how important it is to write readable code. One of the first steps
 | |
| in this direction is the choice of naming convention. It may be quite vague or
 | |
| strictly define the names of all the variables and function in the program,
 | |
| however it surely must somehow allow the reader to distinguish between
 | |
| variable and functions and local variables and member variables from the first
 | |
| glance.
 | |
| <P>The first requirement is commonly respected, but for some strange reasons, the
 | |
| second isn't, even if it's much more important because, after all, the immediate
 | |
| context usually allows you to distinguish a variable from a function in
 | |
| C/C++ code. On the other hand, you <I>cannot</I> say what <TT>x</TT> in the
 | |
| following code fragment is:
 | |
| <PRE>
 | |
|   void Foo::Bar(int x_)
 | |
|   {
 | |
|     ...
 | |
| 
 | |
|     x = x_;
 | |
| 
 | |
|     ...
 | |
|   }
 | |
| </PRE>
 | |
| It might be either a local variable (unluckily the function is too long so you
 | |
| don't see the variable declarations when you look at <TT>x = x_</TT> line), a
 | |
| member variable or a global variable - you have no way of knowing.
 | |
| <P>The wxWindows naming convention gives you, the reader of the code, much more
 | |
| information about <TT>x</TT>. In the code above you know that it's a local
 | |
| variable because:<P>
 | |
| <OL>
 | |
|   <LI>global variables are always prefixed with <TT>g_</TT></LI>
 | |
|   <LI>member variables are always prefixed with <TT>m_</TT></LI>
 | |
|   <LI>static variables are always prefixed with <TT>s_</TT></LI>
 | |
| </OL>
 | |
| <P>Examples:
 | |
| <PRE>
 | |
|   extern int g_x; // of course, 'x' is not the best name for a global...
 | |
| 
 | |
|   void Bar()
 | |
|   {
 | |
|     int x;
 | |
|   }
 | |
| 
 | |
|   class Foo {
 | |
|     public:
 | |
|       void SetX(int x) { m_x = x; }
 | |
|     private:
 | |
|       int m_x;
 | |
|   };
 | |
| </PRE>
 | |
| As you see, it also solves once and for all the old C++ programmer's question:
 | |
| how to call <TT>SetX()</TT> parameter? The answer is simple: just call it
 | |
| <TT>x</TT> because there is no ambiguity with <TT>Foo::m_x</TT>.
 | |
| <P>The prefixes can be combined to give <TT>ms_</TT> and <TT>gs_</TT> for static
 | |
| member (a.k.a. class) variables and static global variables.
 | |
| <P>The convention is, of course, completely worthless if it is not followed:
 | |
| nothing like being sure that <TT>x</TT> is a local variable in the code fragment
 | |
| above and discovering later the following lines in the header:
 | |
| <PRE>
 | |
|   class Foo {
 | |
|     ...
 | |
|     int x;  // I don't like wxWindows naming convention
 | |
|   };
 | |
| </PRE>
 | |
| Please do use these prefixes, they make your code much easier to read. Also
 | |
| please notice that it has nothing to do with the so-called <I>Hungarian notation</I>
 | |
| which is used in wxMSW part of wxWindows code and which encodes the <I>type</I>
 | |
| of the variable in its name - it is actually quite useful in C, but has little
 | |
| or no sense in C++.
 | |
| 
 | |
|     <P><LI><A NAME="no_void_param"></A><B>Don't use <TT>void</TT> for functions without
 | |
|                     arguments</B></LI><P>
 | |
| In ANSI C, <TT>void Foo()</TT> takes an arbitrary number of arbitrarily typed
 | |
| arguments (although the form <TT>void Foo(...)</TT> is preferred) and <TT>void
 | |
| Foo(void)</TT> doesn't take any arguments. In C++, however, the situation is
 | |
| different and both declarations are completely equivalent. As there is no need
 | |
| to write <TT>void</TT> in this situation, let's not write it - it can only be
 | |
| confusing and create an impression that it really means something when it's not
 | |
| at all the case.
 | |
| 
 | |
|     <P><LI><A NAME="no_const_int"></A><B>Don't use <TT>const</TT> for non pointer/reference
 | |
|                     arguments</B></LI><P>
 | |
| In both C and C++ an argument passed by value cannot be modified - or, more
 | |
| precisely, if it is modified in the called function, only the local copy is
 | |
| really changed, not the caller's variable. So, semantically speaking, there is
 | |
| no difference between <TT>void Foo(int)</TT> and <TT>void Foo(const int)</TT>.
 | |
| However, the <TT>const</TT> keyword is confusing here, adds nothing to the code
 | |
| and even cannot be removed if <TT>Foo()</TT> is virtual and overridden (because
 | |
| the names are mangled differently). So, <I>for arguments passed by value</I>
 | |
| you shouldn't use <TT>const</TT>.
 | |
| <P>Of course, it doesn't apply to functions such as
 | |
| <TT>void PrintMessage(const char *text)</TT> where <TT>const</TT> is mandatory.
 | |
|   </OL>
 | |
| </UL>
 | |
| 
 | |
| <P>
 | |
| 
 | |
| <H3>wxWindows rules</H3>
 | |
| <UL>
 | |
|   <P><LI>File location and naming conventions</LI><P>
 | |
|   <OL>
 | |
|     <P><LI><A NAME="file_locations"></LI><B>File locations</B><P>
 | |
| The wxWindows files for each supported platform have their own subdirectories
 | |
| in "include" and "src". So, for example, there is "src/msw", "include/gtk"
 | |
| etc. There are also two special subdirectories called "common" and
 | |
| "generic". The common subdirectory contains the files which are platform
 | |
| independent (wxObject, wxString, ...) and the generic one the generic
 | |
| implementations of GUI widgets, i.e. those which use only other wxWindows
 | |
| classes to implement them. For the platforms where the given functionality
 | |
| cannot be implemented natively, the generic implementation is used and the native
 | |
| one is used for the others. As I feel that it becomes a bit too confusing,
 | |
| here is an example: wxMessageBox function is implemented natively under
 | |
| Windows (where it just calls MessageBox API), but there is also a generic
 | |
| implementation which is used under, for example, GTK. A generic class should
 | |
| normally have a name that distinguishes it from any platform-specific implementation.
 | |
| A #define will allow wxGenericMessageDialog to be wxMessageDialog on some
 | |
| platforms, for example.
 | |
| 
 | |
| <P>This scheme applies not only for the .cpp files, but also for the headers.
 | |
| However, as the program using wxWindows should (ideally) not use any
 | |
| "<TT>#ifdef <platform></TT>" at all, the headers are always included with
 | |
| "<TT>#include <wx/msgdlg.h></TT>" (for example). This file, in turn, includes
 | |
| the right header for given platform. Any new headers should conform to this
 | |
| setup as well to allow including <TT><wx/foo.h></TT> on any platform.<P>
 | |
| 
 | |
| Note that wxWindows implementation files should use quotes when including wxWindows
 | |
| headers, not angled brackets. Applications should use angled brackets. This
 | |
| ensures that the dependencies are correctly handled by the compiler.
 | |
| 
 | |
|     <P><LI><A NAME="include_guards"></LI><B>Include guards</B><P>
 | |
| To minimize the compile time C++ programmers often use so called include
 | |
| guards: for example, in the header file foo.h you might have
 | |
| 
 | |
| <PRE>
 | |
| #ifndef _FOO_H_
 | |
| #define _FOO_H_
 | |
| 
 | |
| ... all header contents ...
 | |
| 
 | |
| #endif
 | |
|  //_FOO_H_
 | |
| </PRE>
 | |
| 
 | |
| In this way, the header will only be included once for the compilation
 | |
| of any .cpp (of course, it still will be included many times for the
 | |
| compilation of the whole project, so it has nothing to do with precompiled
 | |
| headers). wxWindows is no exception and also uses include guards which should use
 | |
| the above form, except for top-level headers which include files with identical
 | |
| names, in which case you should use _FOO_H_BASE_.
 | |
| 
 | |
|     <P><LI><A NAME="pch"></LI><B>Precompiled headers</B><P>
 | |
| The precompiled headers greatly (we're speaking about orders of hundreds of
 | |
| percent here) reduce the compilation time. wxWindows uses them if the target
 | |
| compiler supports them (it knows about MS Visual C++, Borland C++ and g++).
 | |
| You should include all the headers included from <TT><wx/wx_prec.h></TT> only
 | |
| inside "<TT>#if !USE_PRECOMP</TT>" to avoid unnecessary overhead in the case
 | |
| when the precompiled headers are used.<P>
 | |
| 
 | |
| The start of a cpp implementation file after the heading might look like this:<P>
 | |
| 
 | |
| <PRE>
 | |
| #ifdef __GNUG__
 | |
| #pragma implementation "bitmap.h"
 | |
| #endif
 | |
| 
 | |
| // For compilers that support precompilation, includes "wx.h".
 | |
| #include "wx/wxprec.h"
 | |
| 
 | |
| #ifdef __BORLANDC__
 | |
| #pragma hdrstop
 | |
| #endif
 | |
| 
 | |
| #ifndef WX_PRECOMP
 | |
| #include <stdio.h>
 | |
| #include "wx/setup.h"
 | |
| #include "wx/list.h"
 | |
| #include "wx/utils.h"
 | |
| #include "wx/app.h"
 | |
| #include "wx/palette.h"
 | |
| #include "wx/bitmap.h"
 | |
| #include "wx/icon.h"
 | |
| #endif
 | |
| 
 | |
| #include "wx/msw/private.h"
 | |
| #include "assert.h"
 | |
| </PRE>
 | |
| 
 | |
| 
 | |
| <P>Any header file should containg the following lines:
 | |
| <PRE>
 | |
| #ifdef __GNUG__
 | |
|   #pragma interface "foo.h"
 | |
| #endif
 | |
| </PRE>
 | |
| and the corresponding .cpp file:
 | |
| <PRE>
 | |
| #ifdef __GNUG__
 | |
|   #pragma  implementation "foo.h"
 | |
| #endif
 | |
| </PRE> for g++ compilation.
 | |
|   </OL>
 | |
| 
 | |
|   <P><LI>File layout and indentation</LI><P>
 | |
|   <OL>
 | |
|     <P><LI><A NAME="wxwin_header"></LI><B>wxWindows standard header</B> <a href="header.txt">here</a>. The
 | |
| copyright holder is the original author. It is assumed the author does not assert copyright,
 | |
| under the terms of the wxWindows licence. This is a legal interpretation of the informal
 | |
| usage 'public domain' (the copyright holder does not assert the copyright).<P>
 | |
|     <P><LI><A NAME="indentation"></LI><B>Indent your code with 4 spaces (no tabs!)</B>
 | |
|     <P><LI><A NAME="class_decl"></LI><B>Order of parts in a class declarations</B><P>
 | |
|   </OL>
 | |
| 
 | |
|   <P><LI>More about naming conventions</LI><P>
 | |
|   <OL>
 | |
|     <P><LI><A NAME="wx_prefix"></LI><B>Use wx or WX prefix for all public symbols</B>.
 | |
| wx should be used for functions and classes, WX for macros.
 | |
|     <P><LI><A NAME="wxdllexport"</LI><B>Use WXDLLEXPORT with all classes/functions in
 | |
|                                 wxMSW/common code</B>
 | |
| The title says it all - every public (in the sense that it is not internal to
 | |
| the library) function or class should have WXDLLEXPORT macro in its
 | |
| declaration to allow compilation of wxWindows as shared library. For example:<P>
 | |
| 
 | |
| <pre>
 | |
| bool WXDLLEXPORT wxYield(void);
 | |
| class WXDLLEXPORT MyClass;  // (for forward declarations and real declarations)
 | |
| WXDLLEXPORT_DATA(extern wxApp*) wxTheApp;
 | |
| </pre>
 | |
| 
 | |
| The reason for the strange syntax for data is that some compilers use different
 | |
| keyword ordering for exporting data.
 | |
| 
 | |
|     <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
 | |
| the value of a member variable) with either <TT>Set</TT> or <TT>Get</TT>.
 | |
| 
 | |
|     <P><LI><A NAME="constants"></LI><B>wxNAMING_CONSTANTS</B><P>
 | |
| The constants in wxWindows code should be defined using <TT>enum</TT> C++
 | |
| keyword (and not with <TT>#define</TT> or <TT>static const int</TT>). They
 | |
| should be declared in the global scope (and not inside class declaration) and
 | |
| their names should start with a <TT>wx</TT> prefix. Finally, the constants
 | |
| should be in all capital letters (except the first 2) to make it easier to
 | |
| distinguish them from the variables with underscores separating the words.
 | |
| 
 | |
| <P>For example, file-related constants should be declared like this:
 | |
| <pre>
 | |
| enum
 | |
| {
 | |
|     wxFILEOPEN_READ,
 | |
|     wxFILEOPEN_WRITE,
 | |
|     wxFILEOPEN_READWRITE
 | |
| };
 | |
| </pre>
 | |
| 
 | |
|   </OL>
 | |
| 
 | |
|   <P><LI>Miscellaneous</LI><P>
 | |
|   <OL>
 | |
|     <P><LI><A NAME="forward_decl"></LI><B>Use forward declarations whenever possible</B><P>
 | |
| It's really a trivial piece of advice, but remember that using forward declarations
 | |
| instead of including the header of corresponding class is better because not
 | |
| only does it minimize the compile time, it also simplifies the dependencies
 | |
| between different source files.
 | |
| <P>On a related subject, in general, you should try not to include other
 | |
| headers from a header file.
 | |
| 
 | |
|     <P><LI><A NAME="debug_macros"></LI><B>Use debugging macros</B><P>
 | |
| wxWindows provides the debugging macros <TT>wxASSERT, wxFAIL</TT> and
 | |
| <TT>wxCHECK_RET</TT> in <TT><wx/wx.h></TT> file. Please use them as often as
 | |
| you can - they will never do you any harm but can greatly simplify the bug
 | |
| tracking both for you and for others.
 | |
| <P>Also, please use <TT>wxFAIL_MSG("not implemented")</TT> instead of writing
 | |
| stubs for not (yet) implemented functions which silently return incorrect
 | |
| values - otherwise, a person using a not implemented function has no idea that
 | |
| it is, in fact, not implemented.
 | |
| <P>As all debugging macros only do something useful if the symbol
 | |
| <TT>__WXDEBUG__</TT> is defined, you should compile your programs in debug mode to profit
 | |
| from them.
 | |
|   </OL>
 | |
| </UL>
 | |
| 
 | |
| <P>
 | |
| 
 | |
| <HR>
 | |
| Please send any comments to <A HREF=mailto:zeitlin@dptmaths.ens-cachan.fr>Vadim Zeitlin</A>.
 | |
| 
 | |
| </font>
 | |
| 
 | |
| </BODY>
 | |
| </HTML>
 |