X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/172d3acb55b52a5ed15fc7c78a38825978bbc5c8..07fce3c2f91978b00eef7a74615badb374774fc0:/docs/html/standard.htm diff --git a/docs/html/standard.htm b/docs/html/standard.htm index 61d507667e..0f2b556230 100644 --- a/docs/html/standard.htm +++ b/docs/html/standard.htm @@ -24,7 +24,7 @@ wxWindows Programmer Style Guide by Vadim Zeitlin

This guide is intended for people who are (or intending to start) writing code -for wxWindows class library. +for wxWindows class library.

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.

Acknowledgements: This guide is partly based on +HREF="http://www.mozilla.org/hacking/portable-cpp.html" target=_top> C++ portability guide by David Williams.

@@ -52,14 +52,22 @@ C++ portability guide by David Williams.

  • Don't use nested classes

  • +
  • Other compiler limitations
  • +
      +
    1. Use ternary operator ?: carefully
    2. +
    3. Don't use initializers with automatic arrays
    4. +
    5. Always have at least one constructor in a class with destructor
    6. +
    +
  • General recommendations
    1. +
    2. No C++ comments in C code>
    3. No global variables with constructor
    4. Turn on all warnings and eradicate them
    5. Don't rely on sizeof(int) == 2...
    6. No assignments in conditional expressions
    7. -
    8. Use #if 0 rather than comments to temporarily - disable blocks of code
    9. +
    10. Use #if 0 rather than comments to temporarily disable blocks of code
    11. +
    12. Avoid overloaded virtual functions
    13. Don't use extra semi-colons on top level

    @@ -70,15 +78,14 @@ C++ portability guide by David Williams.
  • Avoid carriage returns in cross-platform code
  • Use only lower letter filenames
  • Terminate the files with a new-line
  • +
  • Avoid globals differing by case only

  • Style choices
    1. Naming conventions: use m_ for members
    2. -
    3. Don't use void for functions without - arguments
    4. -
    5. Don't use const for non pointer/reference - arguments
    6. +
    7. Don't use void for functions without arguments
    8. +
    9. Don't use const for non pointer/reference arguments
    @@ -105,8 +112,7 @@ C++ portability guide by David Williams.
  • More about naming conventions
    1. Use wx or WX prefix for all public symbols
    2. -
    3. Use WXDLLEXPORT with all classes/functions in - wxMSW/common code
    4. +
    5. Use WXDLLEXPORT with all classes/functions in wxMSW/common code
    6. Use Set/Get prefixes for accessors
    7. wxNAMING_CONSTANTS
    @@ -332,6 +338,53 @@ you can try the following:

    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). + + +
    +

  • Other compiler limitations
  • +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. + +

      +

    1. Use ternary operator ?: carefully
    2. + The ternary operator ?: 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. +

      Workaround: use if/else instead. +

      +    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;
      +
      + +

    3. Don't use initializers with automatic arrays
    4. +The initializers for automatic array variables are not supported by some older +compilers. For example, the following line +

      +    int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
      +
      +will fail to compile with HP-UX C++ compiler. +

      Workaround: either make the array static or initialize each item +separately: in the (stupid) example above, the array should be definitely +declared as static const (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. + +

    5. Always have at least one constructor in a class with destructor
    6. +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.


    @@ -343,6 +396,18 @@ which must 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.
      +

    1. No C++ comments in C code>
    2. +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 include/wx/setup.h and include/wx/expr.h. + +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. +

    3. No global variables with constructors
    4. In C++, the constructors of global variables are called before the main() function (or WinMain() or any other program entry point) @@ -444,6 +509,70 @@ instead of The reason is simple: if there are any /* ... */ comments inside ... the second version will, of course, miserably fail. +

    5. Avoid overloaded virtual functions
    6. + +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: + +

      +    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!
      +
      + +will fail to compile because the base class function taking filename +is hidden by the virtual function overriden in the derived class (this is +known as [virtual] function name hiding problem in C++). + +

      +The standard solution to this problem in wxWindows (where we have such +situations quite often) is to make both Read() functions not virtual +and introduce a single virtual function DoRead(). 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!). +

      +So, the above declarations should be written as: +

      +    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) { ... }
      +    };
      +
      + +This technique is widely used in many of wxWindows classes - for example, +wxWindow has more than a dozen of DoXXX() functions which +allows to have many overloaded versions of commonly used methods such as +SetSize() +

    7. Don't use extra semi-colons on top level
    8. Some compilers don't pay any attention to extra semicolons on top level, as in

      @@ -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.
      +
      +    

    9. Avoid globals differing by case only
    10. +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. GetId is the same as GetID. +


    @@ -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. -

    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 -"#if !USE_SHARED_LIBRARY" and in the #if USE_SHARED_LIBRARY -case you should put them inside common/cmndata.cpp file. -

  • Use Set/Get prefixes for accessors

    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