X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ee1aaf9996f831c29443ddf1673784e8c9fac3a9..bae2dc62af49b5a870bbabd9473a92921736a6f0:/docs/html/standard.htm diff --git a/docs/html/standard.htm b/docs/html/standard.htm deleted file mode 100644 index 15ee6ef106..0000000000 --- a/docs/html/standard.htm +++ /dev/null @@ -1,882 +0,0 @@ -<HTML> -<HEAD> - <TITLE>wxWindows Programmer Style Guide</TITLE> -</HEAD> - -<BODY> - -<a name="top"></a> - -<font face="Arial, Lucida Sans, Helvetica"> - -<table width=100% border=4 cellpadding=5 cellspacing=0> -<tr> -<td bgcolor="#660000"> -<font size=+1 face="Arial, Lucida Sans, Helvetica" color="#FFFFFF"> -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_ternarywithobjects">Use ternary operator ?: carefully</A></LI> - </OL> - <BR> - <LI>General recommendations</LI> - <OL> - <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> - </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 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> - - <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_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> -</OL> - - <BR> - <LI>General recommendations</B></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_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</B></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. - </OL> - - <BR> - <LI>Style choices</B></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> -It's extremely important 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. There -is a reason for it (can anyone remember what this is?). - - <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>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>#if !USE_SHARED_LIBRARY</TT>" and in the <TT>#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 -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>