]>
Commit | Line | Data |
---|---|---|
97979ddf JS |
1 | <HTML> |
2 | <HEAD> | |
3 | <TITLE>wxWindows Programmer Style Guide</TITLE> | |
4 | </HEAD> | |
5 | ||
6 | <BODY> | |
7 | ||
8 | <a name="top"></a> | |
9 | ||
10 | <font face="Arial, Lucida Sans, Helvetica"> | |
11 | ||
f6bcfd97 | 12 | <table width=100% border=0 cellpadding=5 cellspacing=0> |
97979ddf | 13 | <tr> |
f6bcfd97 BP |
14 | <td bgcolor="#C4ECF9"> |
15 | <font size=+1 face="Arial, Lucida Sans, Helvetica" color="#000000"> | |
97979ddf JS |
16 | wxWindows Programmer Style Guide |
17 | </font> | |
18 | </td> | |
19 | </tr> | |
20 | </table> | |
21 | ||
22 | <P> | |
23 | ||
24 | by <A HREF=mailto:zeitlin@dptmaths.ens-cachan.fr>Vadim Zeitlin</A><P> | |
25 | ||
26 | This guide is intended for people who are (or intending to start) writing code | |
b4fe5125 | 27 | for <A HREF="http://www.wxwindows.org" target=_top>wxWindows</A> class library. |
97979ddf JS |
28 | |
29 | <P> | |
30 | The guide is separated into two parts: the first one addresses the general | |
31 | compatibility issues and is not wxWindows-specific. The advises in this part | |
32 | will hopefully help you to write programs which compile and run on greater | |
33 | variety of platforms. The second part details the wxWindows code organization and | |
34 | its goal it to make wxWindows as uniform as possible without imposing too | |
35 | many restrictions on the programmer. | |
36 | <P> | |
172d3acb | 37 | Acknowledgements: This guide is partly based on <A |
b4fe5125 | 38 | HREF="http://www.mozilla.org/hacking/portable-cpp.html" target=_top> |
97979ddf JS |
39 | C++ portability guide</A> by David Williams. |
40 | ||
41 | <P> | |
42 | <H3>General C++ Rules</H3> | |
43 | <UL> | |
44 | <LI>New or not widely supported C++ features</LI> | |
45 | <OL> | |
46 | <LI><A HREF="#no_templates">Don't use C++ templates</A></LI> | |
47 | <LI><A HREF="#no_exceptions">Don't use C++ exceptions</A></LI> | |
48 | <LI><A HREF="#no_rtti">Don't use RTTI</A></LI> | |
49 | <LI><A HREF="#no_namespaces">Don't use namespaces</A></LI> | |
50 | <LI><A HREF="#no_stl">Don't use STL</A></LI> | |
51 | <LI><A HREF="#no_fordecl">Don't declare variables inside <TT>for()</TT></A></LI> | |
52 | <LI><A HREF="#no_nestedclasses">Don't use nested classes</A></LI> | |
f6bcfd97 | 53 | <LI><A HREF="#no_newlogicalops">Don't use new logical operators keywords</A></LI> |
619fda4f VZ |
54 | </OL> |
55 | <BR> | |
56 | <LI>Other compiler limitations</LI> | |
57 | <OL> | |
00ded554 | 58 | <LI><A HREF="#no_ternarywithobjects">Use ternary operator ?: carefully</A></LI> |
619fda4f VZ |
59 | <LI><A HREF="#no_autoaggregate">Don't use initializers with automatic arrays</A></LI> |
60 | <LI><A HREF="#no_dtorswithoutctor">Always have at least one constructor in a class with destructor</A></LI> | |
97979ddf JS |
61 | </OL> |
62 | <BR> | |
63 | <LI>General recommendations</LI> | |
64 | <OL> | |
58aefa56 | 65 | <LI><A HREF="#no_cppcommentsinc">No C++ comments in C code></A></LI> |
97979ddf JS |
66 | <LI><A HREF="#no_globals">No global variables with constructor</A></LI> |
67 | <LI><A HREF="#no_warnings">Turn on all warnings and eradicate them</A></LI> | |
68 | <LI><A HREF="#no_assume_sizeof">Don't rely on <TT>sizeof(int) == 2</TT>...</A></LI> | |
69 | <LI><A HREF="#no_assignment_in_if">No assignments in conditional expressions</A></LI> | |
ae8b97cf VZ |
70 | <LI><A HREF="#no_comment_code">Use <TT>#if 0</TT> rather than comments to temporarily disable blocks of code</A></LI> |
71 | <LI><A HREF="#no_overloaded_virtuals">Avoid overloaded virtual functions</A></LI> | |
97979ddf JS |
72 | <LI><A HREF="#no_extra_semicolon">Don't use extra semi-colons on top level</A></LI> |
73 | </OL> | |
74 | <BR> | |
75 | <LI>Unix/DOS differences</LI> | |
76 | <OL> | |
77 | <LI><A HREF="#use_cpp_ext">Use .cpp for C++ source file extension</A></LI> | |
78 | <LI><A HREF="#no_backslash">Don't use backslash ('\\') in #includes</A></LI> | |
79 | <LI><A HREF="#no_carriagereturn">Avoid carriage returns in cross-platform code</A></LI> | |
80 | <LI><A HREF="#no_caps_in_filenames">Use only lower letter filenames</A></LI> | |
81 | <LI><A HREF="#no_incomplete_files">Terminate the files with a new-line</A></LI> | |
e4a71fc3 | 82 | <LI><A HREF="#no_case_only_diff">Avoid globals differing by case only</A></LI> |
97979ddf JS |
83 | </OL> |
84 | <BR> | |
85 | <LI>Style choices</LI> | |
86 | <OL> | |
87 | <LI><A HREF="#naming_conv">Naming conventions: use <TT>m_</TT> for members</A></LI> | |
ae8b97cf VZ |
88 | <LI><A HREF="#no_void_param">Don't use <TT>void</TT> for functions without arguments</A></LI> |
89 | <LI><A HREF="#no_const_int">Don't use <TT>const</TT> for non pointer/reference arguments</A></LI> | |
97979ddf JS |
90 | </OL> |
91 | </UL> | |
92 | ||
93 | <P> | |
94 | ||
95 | <H3>wxWindows Rules</H3> | |
96 | <UL> | |
97 | <LI>Files location and naming conventions</LI> | |
98 | <OL> | |
99 | <LI><A HREF="#file_locations">File locations</A></LI> | |
100 | <LI><A HREF="#include_guards">Include guards</A></LI> | |
101 | <LI><A HREF="#pch">Precompiled headers</A></LI> | |
102 | </OL> | |
103 | ||
104 | <BR> | |
105 | <LI>File layout and indentation</LI> | |
106 | <OL> | |
107 | <LI><A HREF="#wxwin_header">wxWindows standard header</A></LI> | |
108 | <LI><A HREF="#indentation">Indent your code with 4 spaces (no tabs!)</A></LI> | |
109 | <LI><A HREF="#class_decl">Order of parts in a class declarations</A></LI> | |
110 | </OL> | |
172d3acb | 111 | |
97979ddf JS |
112 | <BR> |
113 | <LI>More about naming conventions</LI> | |
114 | <OL> | |
115 | <LI><A HREF="#wx_prefix">Use wx or WX prefix for all public symbols</A></LI> | |
e4a71fc3 | 116 | <LI><A HREF="#wxdllexport">Use WXDLLEXPORT with all classes/functions in wxMSW/common code</A></LI> |
97979ddf | 117 | <LI><A HREF="#set_get">Use Set/Get prefixes for accessors</A></LI> |
172d3acb | 118 | <LI><A HREF="#constants">wxNAMING_CONSTANTS</A></LI> |
97979ddf JS |
119 | </OL> |
120 | ||
121 | <BR> | |
122 | <LI>Miscellaneous</LI> | |
123 | <OL> | |
124 | <LI><A HREF="#forward_decl">Use forward declarations whenever possible</A></LI> | |
125 | <LI><A HREF="#debug_macros">Use debugging macros</A></LI> | |
126 | </OL> | |
127 | </UL> | |
128 | ||
129 | <HR> | |
130 | ||
131 | <H3>General C++ Rules</H3> | |
132 | <UL> | |
133 | <LI>New or not widely supported C++ features</LI> | |
172d3acb | 134 | |
97979ddf JS |
135 | <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 |
136 | supported by all compilers. Moreover, when they're supported, there are | |
137 | differences between different vendor's implementations. It's understandable that | |
138 | you might love one (or all) of these features, but you surely can write C++ | |
139 | programs without them. Where possible, workarounds to compensate for absence | |
140 | of your favourite C++ abilities are indicated. | |
141 | <P>Just to suppress any doubts that there are compilers which don't support | |
142 | these new features, you can think about Win16 (a.k.a. Win 3.1) compilers, | |
143 | <I>none</I> of which supports <I>any</I> feature from the list below. | |
172d3acb | 144 | |
97979ddf JS |
145 | <OL> |
146 | <P><LI><A NAME="no_templates"></A><B>Don't use C++ templates</B></LI><P> | |
147 | Besides the reasons mentioned above, template usage also makes the | |
148 | program compile much slower (200%-300% is not uncommon) and their support | |
149 | even in the compilers which have had it for a long time is far from perfect | |
150 | (the best example is probably gcc). | |
151 | <P><U>Workaround</U>: The things you would like to use templates for are, | |
152 | most commonly, polymorphic containers (in the sense that they can contain objects of | |
153 | any type without compromising C++ type system, i.e. using <TT>void *</TT> | |
154 | is out of question). wxWindows provides <A HREF="TODO">dynamic | |
155 | arrays and lists</A> which are sufficient in 99% of cases - please don't hesitate | |
172d3acb | 156 | to use them. Lack of template is not a reason to use static arrays or |
97979ddf JS |
157 | type-less (passing by <TT>void *</TT>) containers. |
158 | ||
159 | <P><LI><A NAME="no_exceptions"></A><B>Don't use C++ exceptions</B></LI><P> | |
160 | The C++ exception system is an error-reporting mechanism. Another reasons not to use it, | |
161 | besides portability, are the performance penalty it imposes (small, but, at least for | |
162 | current compilers, non-zero), and subtle problems with | |
163 | memory/resource deallocation it may create (the place where you'd like to use | |
164 | C++ exceptions most of all are the constructors, but you need to be very | |
165 | careful in order to be able to do it). | |
166 | <P><U>Workaround</U>: there is no real workaround, of course, or the exceptions | |
167 | wouldn't have been added to the language. However, there are several rules which | |
168 | might help here:<P> | |
169 | ||
170 | <OL> | |
171 | <LI>Every function returns an integer (or at least boolean) error code. | |
172 | <P>There is no such thing as a function that never fails - even if it can't | |
173 | fail now, it might do it later, when modified to be more powerful/general. | |
174 | Put the <TT>int</TT> or <TT>bool</TT> return type from the very beginning!<P> | |
175 | </LI><LI>Every function you call may fail - check the return code! | |
176 | <P>Never rely on the function's success, always test for a possible error.<P> | |
177 | </LI><LI>Tell the user about the error, don't silently ignore them. | |
178 | <P>Exceptions are always caught and, normally, processed when they're | |
179 | caught. In the same manner, the error return code must always be processed | |
180 | somehow. You may choose to ignore it, but at least tell the user that | |
181 | something wrong happened using <A HREF="TODO"><TT>wxLogError</TT></A> or | |
182 | <A HREF="TODO"><TT>wxLogWarning</TT></A> functions. All wxWindows | |
183 | functions (must) log the error messages on failure - this can be disabled | |
184 | by using <A HREF="TODO">wxLogNull</A> object before calling it. | |
185 | <P>Examples:<UL> | |
186 | <LI><I>Wrong</I>: | |
187 | <PRE> | |
188 | void ReadAddressBookFile(const wxString& strName) | |
189 | { | |
190 | wxFile file; | |
172d3acb | 191 | |
97979ddf JS |
192 | if ( !file.Open(strFile) ) |
193 | return; | |
172d3acb | 194 | |
97979ddf JS |
195 | ...process it... |
196 | } | |
197 | </PRE> | |
198 | </LI><LI><I>Correct</I>: | |
199 | <PRE> | |
200 | // returns false if the address book couldn't be read | |
201 | bool ReadAddressBookFile(const wxString& strName) | |
202 | { | |
203 | wxFile file; | |
172d3acb | 204 | |
97979ddf JS |
205 | if ( !file.Open(strFile) ) { |
206 | // wxFile logged an error because file couldn't be opened which | |
207 | // contains the system error code, however it doesn't know what | |
208 | // this file is for and an error message "can't open $GLCW.ADB" | |
209 | // can be quite confusing for the user. Here we say what we mean. | |
172d3acb | 210 | wxLogError("Can't read address book from '%s'!", |
97979ddf JS |
211 | strName.c_str()); |
212 | return false; | |
213 | } | |
172d3acb | 214 | |
97979ddf | 215 | ...process it... |
172d3acb | 216 | |
97979ddf JS |
217 | return true; |
218 | } | |
219 | </PRE> | |
220 | or, if it's not an error if file doesn't exist (here we could just check | |
221 | its existence, but let's suppose that there is no <TT>wxFile::Exists()</TT>) | |
222 | we can also write: | |
223 | <PRE> | |
224 | // returns false if address book file doesn't exist | |
225 | bool ReadAddressBookFile(const wxString& strName) | |
226 | { | |
227 | wxFile file; | |
172d3acb | 228 | |
97979ddf JS |
229 | // start a block inside which all log messages are suppressed |
230 | { | |
231 | wxLogNull noLog; | |
232 | if ( !file.Open(strFile) ) | |
233 | return false; | |
234 | } | |
172d3acb | 235 | |
97979ddf | 236 | ...process it... |
172d3acb | 237 | |
97979ddf JS |
238 | return true; |
239 | } | |
240 | </PRE></LI> | |
241 | </UL> | |
242 | </OL> | |
172d3acb | 243 | |
97979ddf JS |
244 | <P><LI><A NAME="no_rtti"></A><B>Don't use RTTI</B></LI><P> |
245 | RTTI stands for Run-Time Type Information and there is probably no other | |
246 | reason not to use it except the portability issue and the fact that it adds | |
247 | <TT>sizeof(void *)</TT> bytes to any class having virtual functions (at least, | |
248 | in the implementations I'm aware of). | |
249 | <P><U>Workaround</U>: use wxWindows RTTI system which allows you to do almost | |
250 | everything which the new C++ RTTI, except that, of course, you have to use | |
172d3acb | 251 | macros instead of the (horrible looking, BTW) <TT>dynamic_cast</TT>. |
97979ddf JS |
252 | |
253 | <P><LI><A NAME="no_namespaces"></A><B>Don't use namespaces</B></LI><P> | |
254 | This topic is subject to change with time, however for the moment all wxWindows | |
255 | classes/functions live in the global namespace. | |
256 | <P><U>Workaround</U>: None. | |
257 | ||
258 | <P><LI><A NAME="no_stl"></A><B>Don't use STL</B></LI><P> | |
259 | STL is the new C++ standard library, proposing all kinds of template containers | |
260 | and generic algorithm implementations. Templates are the heart (and almost | |
261 | everything else) of the library, so its usage is out of question. Besides, even | |
262 | with the compilers which do support templates, STL has many of its own problems, | |
263 | there are many "not 100% standard compatible" vendor implementations, none of existing debuggers understands its | |
264 | complicated data structures, ... the list can go on (almost) forever. | |
265 | <P><U>Workaround</U>: Use wxString, dynamic arrays and lists and other wxWindows | |
266 | classes. wxString has many of the most often used functions of std::string STL | |
267 | class (typedef to be precise). | |
268 | <P><LI><A NAME="no_fordecl"></A><B>Don't declare variables inside <TT>for() | |
269 | </TT></B></LI><P> | |
270 | The scope of a variable declared inside <TT>for()</TT> statement changed several | |
271 | years ago, however many compilers still will complain about second declaration | |
272 | of <TT>i</TT> in the following code: | |
273 | <PRE> | |
f6bcfd97 | 274 | for ( int i = 0; i < 10; i++ ) { |
97979ddf JS |
275 | ... |
276 | } | |
277 | ||
278 | ... | |
279 | ||
f6bcfd97 | 280 | for ( int i = 0; i < 10; i++ ) { |
97979ddf JS |
281 | ... |
282 | } | |
283 | </PRE> | |
f6bcfd97 | 284 | even though if it's perfectly legal now. |
97979ddf JS |
285 | <P><U>Workaround</U>: write this instead: |
286 | <PRE> | |
287 | int i; | |
f6bcfd97 | 288 | for ( i = 0; i < 10; i++ ) { |
97979ddf JS |
289 | ... |
290 | } | |
291 | ||
292 | ... | |
293 | ||
f6bcfd97 | 294 | for ( i = 0; i < 10; i++ ) { |
97979ddf JS |
295 | ... |
296 | } | |
297 | </PRE> | |
f6bcfd97 BP |
298 | or, even better, use different names for the variables in the different for |
299 | loops (in particular, avoid mute variable names like <tt>i<tt> above) - then | |
300 | you can declare them in the loop statement and don't pollute the outer name | |
301 | space with local loop variables. | |
97979ddf JS |
302 | |
303 | <P><LI><A NAME="no_nestedclasses"></A><B>Don't use nested classes</B></LI><P> | |
304 | Nested classes are, without doubt, a very good thing because they allow to hide | |
305 | "private" (in the sense that they're used only inside the library) classes and, | |
306 | generally, put the related things together. | |
307 | <P>Unfortunately, some compilers have trouble understanding them, so we must | |
308 | sacrifice the ideals of software design to get a working program in this case. | |
309 | <P><U>Workaround</U>: instead of | |
310 | <PRE> | |
311 | // in the header | |
312 | class PublicLibClass { | |
313 | ... | |
314 | private: | |
315 | class PrivateLibClass { ... } m_object; | |
316 | }; | |
317 | </PRE> | |
318 | you can try the following: | |
319 | <PRE> | |
320 | // in the header | |
321 | class PrivateLibClass; // fwd decl | |
322 | class PublicLibClass { | |
323 | ... | |
324 | private: | |
325 | class PrivateLibClass *m_pObject; | |
326 | }; | |
172d3acb | 327 | |
97979ddf JS |
328 | // in the .cpp file |
329 | class PrivateLibClass { ... }; | |
172d3acb | 330 | |
97979ddf JS |
331 | PublicLibClass::PublicLibClass() |
332 | { | |
333 | m_pObject = new PrivateLibClass; | |
172d3acb | 334 | |
97979ddf JS |
335 | ... |
336 | } | |
172d3acb | 337 | |
97979ddf JS |
338 | PublicLibClass::~PublicLibClass() |
339 | { | |
340 | delete m_pObject; | |
341 | } | |
342 | </PRE> | |
343 | <P>A nice side effect is that you don't need to recompile all the files | |
344 | including the header if you change the PrivateLibClass declaration (it's | |
345 | an example of a more general interface/implementation separation idea). | |
f6bcfd97 BP |
346 | |
347 | <P><LI><A NAME="no_newlogicalops"></A><B>Don't use new logical operators keywords</B></LI><P> | |
348 | The C++ standard has introduced the following new reserved words: <tt>or</tt>, | |
349 | <tt>and</tt>, <tt>not</tt>, <tt>xor</tt>, <tt>bitand</tt>, <tt>bitor</tt>, | |
350 | <tt>compl</tt>, <tt>and_eq</tt>, <tt>or_eq</tt>, <tt>not_eq</tt>, | |
351 | <tt>or_eq</tt> which can be used instead of the usual C operations &&, | |
352 | ||, ~ etc. | |
353 | <P>This wonderful (and not backwards compatible in addition to being | |
354 | absolutely useless) new feature means that these new keywords should not be | |
355 | used as the variable names - even if current compilers usually will accept | |
356 | this, your code will break in the future. For most of the keywords, using them | |
357 | as variable names is quite unlikely, but <tt>or</tt> and <tt>compl</tt> were | |
358 | used in the wxWindows sources which seems to indicate that they are the most | |
359 | likely candidates. | |
360 | <P>It goes without saying that these new keywords should not be used instead | |
361 | of the tradional C operators neither both because most compilers don't accept | |
362 | them and because using them in C code makes it less readable. | |
619fda4f VZ |
363 | </OL> |
364 | ||
365 | <BR> | |
f6bcfd97 | 366 | <LI>Other compiler limitations</LI><P> |
619fda4f VZ |
367 | This section lists the less obvious limitations of the current C++ compilers |
368 | which are less restrictive than the ones mentioned in the previous section but | |
369 | are may be even more dangerous as a program which compiles perfectly well on | |
370 | some platform and seems to use only standard C++ featurs may still fail to | |
371 | compile on another platform and/or with another compiler. | |
00ded554 | 372 | |
619fda4f | 373 | <OL> |
00ded554 VZ |
374 | <P><LI><A NAME="no_ternarywithobjects"></A><B>Use ternary operator ?: carefully</B></LI><P> |
375 | The ternary operator <TT>?:</TT> shouldn't be used with objects (i.e. if any | |
f6bcfd97 | 376 | of its operands are objects) because some compilers (notably Borland C++) fail |
00ded554 VZ |
377 | to compile such code. |
378 | <P><U>Workaround</U>: use <TT>if/else</TT> instead. | |
379 | <PRE> | |
380 | wxString s1, s2; | |
381 | ||
382 | // Borland C++ won't compile the line below | |
f6bcfd97 | 383 | wxString s = s1.Len() < s2.Len() ? s1 : s2; |
00ded554 VZ |
384 | |
385 | // but any C++ compiler will compile this | |
386 | wxString s; | |
f6bcfd97 | 387 | if ( s1.Len() < s2.Len() ) |
00ded554 VZ |
388 | s = s1; |
389 | else | |
390 | s = s2; | |
391 | </PRE> | |
619fda4f VZ |
392 | |
393 | <P><LI><A NAME="no_autoaggregate"></A><B>Don't use initializers with automatic arrays</B></LI><P> | |
394 | The initializers for automatic array variables are not supported by some older | |
395 | compilers. For example, the following line | |
396 | <PRE> | |
397 | int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | |
398 | </PRE> | |
399 | will fail to compile with HP-UX C++ compiler. | |
400 | <P><U>Workaround</U>: either make the array static or initialize each item | |
401 | separately: in the (stupid) example above, the array should be definitely | |
402 | declared as <TT>static const</TT> (assuming that the leap years are dealt with | |
403 | elsewhere somehow...) which is ok. When an array is really not const, you | |
404 | should initialize each element separately. | |
405 | ||
406 | <P><LI><A NAME="no_dtorswithoutctor"></A><B>Always have at least one constructor in a class with destructor</B></LI><P> | |
407 | It is a good rule to follow in general, but some compilers (HP-UX) enforce it. | |
408 | So even if you are sure that the default constructor for your class is ok but | |
409 | it has a destructor, remember to add an empty default constructor to it. | |
97979ddf JS |
410 | </OL> |
411 | ||
412 | <BR> | |
f6bcfd97 | 413 | <LI>General recommendations</LI><P> |
97979ddf JS |
414 | While the recommendations in the previous section may not apply to you if you're |
415 | only working with perfect compilers which implement the very newest directives of | |
172d3acb | 416 | C++ standard, this section contains compiler- (and language-) independent advice |
97979ddf | 417 | which <B>must</B> be followed if you wish to write correct, i.e. working, programs. It |
172d3acb | 418 | also contains some C/C++ specific remarks in the end which are less |
97979ddf JS |
419 | important. |
420 | <OL> | |
58aefa56 VZ |
421 | <P><LI><A NAME="no_cppcommentsinc"><B>No C++ comments in C code></B></LI><P> |
422 | Never use C++ comments in C code - not all C compilers/preprocessors | |
423 | understand them. Although we're mainly concerned with C++ here, there are | |
424 | several files in wxWindows sources tree which are compiled with C compiler. | |
425 | Among them are <TT>include/wx/setup.h</TT> and <TT>include/wx/expr.h</TT>. | |
426 | ||
427 | Another thing related to C vs C++ preprocessor differences is that some old C | |
428 | preprocessors require that all directives start in the first column (while | |
429 | it's generally allowed to have any amount of whitespace before them in C++), | |
430 | so you should start them in the beginning of the line in files which are | |
431 | compiled with C compiler. | |
432 | ||
97979ddf JS |
433 | <P><LI><A NAME="no_globals"></A><B>No global variables with constructors</B></LI><P> |
434 | In C++, the constructors of global variables are called before the | |
172d3acb | 435 | <TT>main()</TT> function (or <TT>WinMain()</TT> or any other program entry point) |
97979ddf JS |
436 | starts executing. Thus, there is no possibility to initialize <I>anything</I> |
437 | before the constructor call. The order of construction is largely | |
438 | implementation-defined, meaning that there is no guarantee that one global | |
439 | object will be initialized before another one (except if they are both defined | |
440 | in the same translation unit, i.e. .cpp file). Most importantly, no custom | |
441 | memory allocation operators are installed at the moment of execution of global | |
442 | variables constructors, so a (less restrictive) rule is that you should have | |
443 | no global variables which allocate memory (or do anything else non-trivial) in | |
444 | the constructor. Of course, if an object doesn't allocate memory in its constructor | |
445 | right now, it may start making it later, so you can only be sure about this if | |
446 | you don't use <I>any</I> variables of object (as opposed to simple: | |
447 | <TT>int</TT>, ...) types. Example: currently, wxString doesn't allocate memory | |
448 | in its default constructor, so you might think that having a global (initially) | |
449 | empty wxString is safe. However, if wxString starts allocating some minimal | |
450 | amount of memory in its default constructor (which doesn't look unreasonable), | |
451 | you would have all kinds of problems with <TT>new</TT> | |
452 | and <TT>delete</TT> operators (overloaded in wxWindows), especially because the first <TT>new</TT> called | |
453 | is the standard one (before wxWindows overloads them) and <TT>delete</TT> will | |
454 | be the overloaded operator. | |
455 | ||
456 | <P><LI><A NAME="no_warnings"></A><B>Turn on all warnings and eradicate them</B></LI><P> | |
457 | Give the compiler a chance to help you - turn on all warnings! You should always | |
458 | use the maximum available warning level of your compiler and understand and | |
459 | correct each of them. If, for whatever reasons, a compiler gives a warning on | |
460 | some perfectly legal line of code and you can't change it, please insert a | |
461 | comment indicating it in the code. Most oftenly, however, all compiler warnings | |
462 | may be avoided (not suppressed!) with minimal changes to your code. | |
463 | ||
464 | <P><LI><A NAME="no_assume_sizeof"></A><B>Don't rely on <TT>sizeof(int) == 2</TT>...</B></LI><P> | |
465 | You should never assume any absolute constraints on data type sizes. Currently, | |
466 | we have 16-bit, 32-bit and 64-bit machines and even inside each class data type | |
467 | sizes are different. A small table illustrates it quite well: | |
468 | <TABLE BORDER COLS=5 WIDTH="100%" NOSAVE > | |
469 | <TR> | |
470 | <TD>Architecture/OS</TD> | |
471 | <TD>sizeof(short)</TD> | |
472 | <TD>sizeof(int)</TD> | |
473 | <TD>sizeof(long)</TD> | |
474 | <TD>sizeof(void *)</TD> | |
475 | </TR> | |
476 | ||
477 | <TR> | |
478 | <TD>i386/Windows 3.1</TD> | |
479 | <TD>2</TD> | |
480 | <TD>2</TD> | |
481 | <TD>4</TD> | |
482 | <TD>2 or 4</TD> | |
483 | </TR> | |
484 | ||
485 | <TR> | |
486 | <TD>i386/Windows 95</TD> | |
487 | <TD>2</TD> | |
488 | <TD>4</TD> | |
489 | <TD>4</TD> | |
490 | <TD>4</TD> | |
491 | </TR> | |
492 | ||
493 | <TR> | |
494 | <TD>Merced/Win64</TD> | |
495 | <TD>2</TD> | |
496 | <TD>4</TD> | |
497 | <TD>4</TD> | |
498 | <TD>8</TD> | |
499 | </TR> | |
500 | ||
501 | <TR> | |
502 | <TD>Alpha/Linux</TD> | |
503 | <TD>???</TD> | |
504 | <TD>???</TD> | |
505 | <TD>???</TD> | |
506 | <TD>???</TD> | |
507 | </TR> | |
508 | </TABLE> | |
509 | ||
510 | <P><LI><A NAME="no_assignment_in_if"></A><B>No assignments in conditional expressions</B></LI><P> | |
511 | Although close to the heart of many C programmers (I plead guilty), code like | |
512 | classical <TT>if ( (c = getchar()) != EOF )</TT> is bad because it prevents you | |
513 | from enabling "assignment in conditional expression" warning (see also | |
172d3acb | 514 | <A HREF="#no_warnings">above</A>) which is helpful to detect common |
97979ddf JS |
515 | mistypes like <TT>if ( x = 2 )</TT> instead of <TT>if ( x == 2 )</TT>. |
516 | ||
517 | <P><LI><A NAME="no_comment_code"></A><B>Use <TT>#if 0</TT> rather than comments to temporarily | |
518 | disable blocks of code</B></LI><P> | |
519 | If you have to temporarily disable some code, use | |
520 | <PRE> | |
521 | #if 0 // VZ: I think this code is unneeded, it probably must be removed | |
522 | ... | |
523 | #endif // 0 | |
524 | </PRE> | |
525 | instead of | |
526 | <PRE> | |
527 | /* | |
528 | ... | |
529 | */ | |
530 | </PRE> | |
531 | The reason is simple: if there are any <TT>/* ... */</TT> comments inside | |
532 | <TT>...</TT> the second version will, of course, miserably fail. | |
533 | ||
ae8b97cf VZ |
534 | <P><LI><A NAME="no_overloaded_virtuals"></A><B>Avoid overloaded virtual functions</B></LI><P> |
535 | ||
536 | You should avoid having overloaded virtual methods in a base class because if | |
537 | any of them is overriden in a derived class, then all others must be overriden | |
538 | as well or it would be impossible to call them on an object of derived class. | |
539 | ||
540 | For example, the following code: | |
541 | ||
542 | <PRE> | |
543 | class Base | |
544 | { | |
545 | public: | |
546 | virtual void Read(wxFile& file); | |
547 | virtual void Read(const wxString& filename); | |
548 | }; | |
549 | ||
550 | class Derived : public Base | |
551 | { | |
552 | public: | |
553 | virtual void Read(wxFile& file) { ... } | |
554 | }; | |
555 | ||
556 | ... | |
557 | ||
558 | Derived d; | |
559 | d.Read("some_filename"); // compile error here! | |
560 | </PRE> | |
561 | ||
562 | will fail to compile because the base class function taking <TT>filename</TT> | |
563 | is hidden by the virtual function overriden in the derived class (this is | |
564 | known as [virtual] function name hiding problem in C++). | |
565 | ||
566 | <P> | |
567 | The standard solution to this problem in wxWindows (where we have such | |
568 | situations quite often) is to make both <TT>Read()</TT> functions not virtual | |
569 | and introduce a single virtual function <TT>DoRead()</TT>. Usually, it makes | |
570 | sense because the function taking a filename is (again, usually) implemented | |
571 | in terms of the function reading from a file anyhow (but making only this | |
572 | functions not virtual won't solve the above problem!). | |
573 | <P> | |
574 | So, the above declarations should be written as: | |
575 | <PRE> | |
576 | class Base | |
577 | { | |
578 | public: | |
579 | void Read(wxFile& file); | |
580 | void Read(const wxString& filename); | |
581 | ||
582 | protected: | |
583 | virtual void DoRead(wxFile& file); | |
584 | }; | |
585 | ||
586 | class Derived : public Base | |
587 | { | |
588 | protected: | |
589 | virtual void DoRead(wxFile& file) { ... } | |
590 | }; | |
591 | </PRE> | |
592 | ||
593 | This technique is widely used in many of wxWindows classes - for example, | |
594 | <TT>wxWindow</TT> has more than a dozen of <TT>DoXXX()</TT> functions which | |
595 | allows to have many overloaded versions of commonly used methods such as | |
596 | <TT>SetSize()</TT> | |
597 | ||
97979ddf JS |
598 | <P><LI><A NAME="no_extra_semicolon"></A><B>Don't use extra semi-colons on top level</B></LI><P> |
599 | Some compilers don't pay any attention to extra semicolons on top level, as in | |
600 | <PRE> | |
601 | class Foo { };; | |
602 | </PRE> | |
603 | while others complain loudly about it. Of course, you would rarely put 2 | |
604 | semicolons yourself, but it may happen if you're using a macro | |
605 | (<TT>IMPLEMENT_something</TT>, for example) which already has a ';' inside and | |
606 | put another one after it. | |
607 | </OL> | |
608 | ||
609 | <BR> | |
f6bcfd97 | 610 | <LI>Unix/DOS differences</LI><P> |
97979ddf JS |
611 | Two operating systems supported by wxWindows right now are (different flavours |
612 | of) Unix and Windows 3.1/95/NT (although Mac, OS/2 and other ports exist/are | |
613 | being developed as well). The main differences between them are summarized | |
614 | here. | |
615 | ||
616 | <OL> | |
617 | <P><LI><A NAME="use_cpp_ext"></A><B>Use .cpp for C++ source file extension</B></LI><P> | |
618 | There is, unfortunately, no standard exceptions for C++ source files. Different | |
619 | people use .C, .cc, .cpp, .cxx, .c++ and probably several others I forgot. Some | |
620 | compilers don't care about extension, but there are also other ones which can't | |
621 | be made to compile any file with "wrong" extension. Such compilers are very | |
622 | common in DOS/Windows land, that's why the .cpp extension is the least likely to | |
623 | cause any problems - it's the standard one under DOS and will probably be | |
624 | accepted by any Unix compiler as well (any counter examples?). The extension | |
625 | for the header files is .h. | |
626 | ||
627 | <P><LI><A NAME="no_backslash"></A><B>Don't use backslash ('\\') in #includes</B></LI><P> | |
628 | Although it's too silly to mention, please don't use backslashes in | |
629 | <TT>#include</TT> preprocessor statement. Even not all Windows compilers accept | |
630 | it, without speaking about all other ones. | |
631 | ||
632 | <P><LI><A NAME="no_carriagereturn"></A><B>Avoid carriage returns in cross-platform code</B></LI><P> | |
633 | This problem will hopefully not arise at all, with CVS taking care of this | |
634 | stuff, however it's perhaps not useless to remember that many Unix compilers | |
635 | (including, but not limited to, gcc) don't accept carriage returns | |
636 | (= <Ctrl-M> = '\r') in C/C++ code. | |
637 | ||
638 | <P><LI><A NAME="no_caps_in_filenames"></A><B>Use only lower case filenames</B></LI><P> | |
639 | DOS/Windows 3.1 isn't case sensitive, Windows 95/NT are case preserving, but not | |
640 | case sensitive. To avoid all kinds of problems with compiling under Unix (or | |
641 | any other fully case-sensitive OS), please use only lower case letters in the | |
642 | filenames. | |
643 | ||
644 | <P><LI><A NAME="no_incomplete_files"></A><B>Terminate the files with a new-line</B></LI><P> | |
645 | While DOS/Windows compilers don't seem to mind, their Unix counterparts don't | |
646 | like files without terminating new-line. Such files also give a warning message | |
647 | when loaded to vim (the Unix programmer's editor of choice :-)), so please think | |
648 | about terminating the last line. | |
e4a71fc3 VZ |
649 | |
650 | <P><LI><A NAME="no_case_only_diff"></A><B>Avoid globals differing by case only</B></LI><P> | |
651 | The linker on VMS is case-insensitive. Therefore all external variables and | |
652 | functions which differ only in case are not recognized by the linker as | |
653 | different, so all externals should differ in more than the case only: | |
079bb992 | 654 | i.e. <TT>GetId</TT> is the same as <TT>GetID</TT>. |
e4a71fc3 | 655 | |
97979ddf | 656 | </OL> |
172d3acb | 657 | |
97979ddf | 658 | <BR> |
f6bcfd97 | 659 | <LI>Style choices</LI><P> |
172d3acb | 660 | All wxWindows specific style guidelines are specified in the next |
97979ddf JS |
661 | section, here are the choices which are not completely arbitrary, |
662 | but have some deeper and not wxWindows-specific meaning. | |
663 | ||
664 | <OL> | |
665 | <P><LI><A NAME="naming_conv"></A><B>Naming conventions: use <TT>m_</TT> for members</B></LI><P> | |
f6bcfd97 BP |
666 | We all know how important it is to write readable code. One of the first steps |
667 | in this direction is the choice of naming convention. It may be quite vague or | |
668 | strictly define the names of all the variables and function in the program, | |
669 | however it surely must somehow allow the reader to distinguish between | |
670 | variable and functions and local variables and member variables from the first | |
671 | glance. | |
97979ddf JS |
672 | <P>The first requirement is commonly respected, but for some strange reasons, the |
673 | second isn't, even if it's much more important because, after all, the immediate | |
674 | context usually allows you to distinguish a variable from a function in | |
675 | C/C++ code. On the other hand, you <I>cannot</I> say what <TT>x</TT> in the | |
676 | following code fragment is: | |
677 | <PRE> | |
678 | void Foo::Bar(int x_) | |
679 | { | |
680 | ... | |
172d3acb | 681 | |
97979ddf | 682 | x = x_; |
172d3acb | 683 | |
97979ddf JS |
684 | ... |
685 | } | |
686 | </PRE> | |
687 | It might be either a local variable (unluckily the function is too long so you | |
688 | don't see the variable declarations when you look at <TT>x = x_</TT> line), a | |
689 | member variable or a global variable - you have no way of knowing. | |
690 | <P>The wxWindows naming convention gives you, the reader of the code, much more | |
691 | information about <TT>x</TT>. In the code above you know that it's a local | |
692 | variable because:<P> | |
693 | <OL> | |
694 | <LI>global variables are always prefixed with <TT>g_</TT></LI> | |
695 | <LI>member variables are always prefixed with <TT>m_</TT></LI> | |
696 | <LI>static variables are always prefixed with <TT>s_</TT></LI> | |
697 | </OL> | |
698 | <P>Examples: | |
699 | <PRE> | |
700 | extern int g_x; // of course, 'x' is not the best name for a global... | |
701 | ||
702 | void Bar() | |
703 | { | |
704 | int x; | |
705 | } | |
706 | ||
707 | class Foo { | |
708 | public: | |
709 | void SetX(int x) { m_x = x; } | |
710 | private: | |
711 | int m_x; | |
712 | }; | |
713 | </PRE> | |
714 | As you see, it also solves once and for all the old C++ programmer's question: | |
715 | how to call <TT>SetX()</TT> parameter? The answer is simple: just call it | |
716 | <TT>x</TT> because there is no ambiguity with <TT>Foo::m_x</TT>. | |
717 | <P>The prefixes can be combined to give <TT>ms_</TT> and <TT>gs_</TT> for static | |
718 | member (a.k.a. class) variables and static global variables. | |
719 | <P>The convention is, of course, completely worthless if it is not followed: | |
720 | nothing like being sure that <TT>x</TT> is a local variable in the code fragment | |
721 | above and discovering later the following lines in the header: | |
722 | <PRE> | |
723 | class Foo { | |
724 | ... | |
725 | int x; // I don't like wxWindows naming convention | |
726 | }; | |
727 | </PRE> | |
728 | Please do use these prefixes, they make your code much easier to read. Also | |
729 | please notice that it has nothing to do with the so-called <I>Hungarian notation</I> | |
730 | which is used in wxMSW part of wxWindows code and which encodes the <I>type</I> | |
731 | of the variable in its name - it is actually quite useful in C, but has little | |
732 | or no sense in C++. | |
733 | ||
734 | <P><LI><A NAME="no_void_param"></A><B>Don't use <TT>void</TT> for functions without | |
735 | arguments</B></LI><P> | |
736 | In ANSI C, <TT>void Foo()</TT> takes an arbitrary number of arbitrarily typed | |
737 | arguments (although the form <TT>void Foo(...)</TT> is preferred) and <TT>void | |
738 | Foo(void)</TT> doesn't take any arguments. In C++, however, the situation is | |
739 | different and both declarations are completely equivalent. As there is no need | |
740 | to write <TT>void</TT> in this situation, let's not write it - it can only be | |
741 | confusing and create an impression that it really means something when it's not | |
742 | at all the case. | |
743 | ||
744 | <P><LI><A NAME="no_const_int"></A><B>Don't use <TT>const</TT> for non pointer/reference | |
745 | arguments</B></LI><P> | |
746 | In both C and C++ an argument passed by value cannot be modified - or, more | |
747 | precisely, if it is modified in the called function, only the local copy is | |
748 | really changed, not the caller's variable. So, semantically speaking, there is | |
749 | no difference between <TT>void Foo(int)</TT> and <TT>void Foo(const int)</TT>. | |
750 | However, the <TT>const</TT> keyword is confusing here, adds nothing to the code | |
751 | and even cannot be removed if <TT>Foo()</TT> is virtual and overridden (because | |
752 | the names are mangled differently). So, <I>for arguments passed by value</I> | |
753 | you shouldn't use <TT>const</TT>. | |
172d3acb | 754 | <P>Of course, it doesn't apply to functions such as |
97979ddf JS |
755 | <TT>void PrintMessage(const char *text)</TT> where <TT>const</TT> is mandatory. |
756 | </OL> | |
757 | </UL> | |
758 | ||
759 | <P> | |
760 | ||
761 | <H3>wxWindows rules</H3> | |
762 | <UL> | |
763 | <P><LI>File location and naming conventions</LI><P> | |
764 | <OL> | |
765 | <P><LI><A NAME="file_locations"></LI><B>File locations</B><P> | |
766 | The wxWindows files for each supported platform have their own subdirectories | |
767 | in "include" and "src". So, for example, there is "src/msw", "include/gtk" | |
768 | etc. There are also two special subdirectories called "common" and | |
769 | "generic". The common subdirectory contains the files which are platform | |
172d3acb | 770 | independent (wxObject, wxString, ...) and the generic one the generic |
97979ddf JS |
771 | implementations of GUI widgets, i.e. those which use only other wxWindows |
772 | classes to implement them. For the platforms where the given functionality | |
773 | cannot be implemented natively, the generic implementation is used and the native | |
774 | one is used for the others. As I feel that it becomes a bit too confusing, | |
775 | here is an example: wxMessageBox function is implemented natively under | |
776 | Windows (where it just calls MessageBox API), but there is also a generic | |
777 | implementation which is used under, for example, GTK. A generic class should | |
778 | normally have a name that distinguishes it from any platform-specific implementation. | |
779 | A #define will allow wxGenericMessageDialog to be wxMessageDialog on some | |
780 | platforms, for example. | |
781 | ||
782 | <P>This scheme applies not only for the .cpp files, but also for the headers. | |
783 | However, as the program using wxWindows should (ideally) not use any | |
784 | "<TT>#ifdef <platform></TT>" at all, the headers are always included with | |
785 | "<TT>#include <wx/msgdlg.h></TT>" (for example). This file, in turn, includes | |
786 | the right header for given platform. Any new headers should conform to this | |
787 | setup as well to allow including <TT><wx/foo.h></TT> on any platform.<P> | |
788 | ||
789 | Note that wxWindows implementation files should use quotes when including wxWindows | |
793867a7 VZ |
790 | headers, not angled brackets. Applications should use angled brackets. This |
791 | ensures that the dependencies are correctly handled by the compiler. | |
97979ddf JS |
792 | |
793 | <P><LI><A NAME="include_guards"></LI><B>Include guards</B><P> | |
794 | To minimize the compile time C++ programmers often use so called include | |
795 | guards: for example, in the header file foo.h you might have | |
796 | ||
797 | <PRE> | |
798 | #ifndef _FOO_H_ | |
799 | #define _FOO_H_ | |
800 | ||
801 | ... all header contents ... | |
802 | ||
803 | #endif | |
804 | //_FOO_H_ | |
805 | </PRE> | |
806 | ||
807 | In this way, the header will only be included once for the compilation | |
808 | of any .cpp (of course, it still will be included many times for the | |
809 | compilation of the whole project, so it has nothing to do with precompiled | |
810 | headers). wxWindows is no exception and also uses include guards which should use | |
811 | the above form, except for top-level headers which include files with identical | |
812 | names, in which case you should use _FOO_H_BASE_. | |
813 | ||
814 | <P><LI><A NAME="pch"></LI><B>Precompiled headers</B><P> | |
815 | The precompiled headers greatly (we're speaking about orders of hundreds of | |
816 | percent here) reduce the compilation time. wxWindows uses them if the target | |
817 | compiler supports them (it knows about MS Visual C++, Borland C++ and g++). | |
818 | You should include all the headers included from <TT><wx/wx_prec.h></TT> only | |
819 | inside "<TT>#if !USE_PRECOMP</TT>" to avoid unnecessary overhead in the case | |
820 | when the precompiled headers are used.<P> | |
821 | ||
822 | The start of a cpp implementation file after the heading might look like this:<P> | |
823 | ||
824 | <PRE> | |
825 | #ifdef __GNUG__ | |
826 | #pragma implementation "bitmap.h" | |
827 | #endif | |
828 | ||
829 | // For compilers that support precompilation, includes "wx.h". | |
830 | #include "wx/wxprec.h" | |
831 | ||
832 | #ifdef __BORLANDC__ | |
833 | #pragma hdrstop | |
834 | #endif | |
835 | ||
836 | #ifndef WX_PRECOMP | |
837 | #include <stdio.h> | |
838 | #include "wx/setup.h" | |
839 | #include "wx/list.h" | |
840 | #include "wx/utils.h" | |
841 | #include "wx/app.h" | |
842 | #include "wx/palette.h" | |
843 | #include "wx/bitmap.h" | |
844 | #include "wx/icon.h" | |
845 | #endif | |
846 | ||
847 | #include "wx/msw/private.h" | |
848 | #include "assert.h" | |
849 | </PRE> | |
850 | ||
851 | ||
852 | <P>Any header file should containg the following lines: | |
853 | <PRE> | |
854 | #ifdef __GNUG__ | |
855 | #pragma interface "foo.h" | |
856 | #endif | |
857 | </PRE> | |
858 | and the corresponding .cpp file: | |
859 | <PRE> | |
860 | #ifdef __GNUG__ | |
861 | #pragma implementation "foo.h" | |
862 | #endif | |
863 | </PRE> for g++ compilation. | |
864 | </OL> | |
865 | ||
866 | <P><LI>File layout and indentation</LI><P> | |
867 | <OL> | |
868 | <P><LI><A NAME="wxwin_header"></LI><B>wxWindows standard header</B> <a href="header.txt">here</a>. The | |
869 | copyright holder is the original author. It is assumed the author does not assert copyright, | |
870 | under the terms of the wxWindows licence. This is a legal interpretation of the informal | |
871 | usage 'public domain' (the copyright holder does not assert the copyright).<P> | |
872 | <P><LI><A NAME="indentation"></LI><B>Indent your code with 4 spaces (no tabs!)</B> | |
873 | <P><LI><A NAME="class_decl"></LI><B>Order of parts in a class declarations</B><P> | |
874 | </OL> | |
172d3acb | 875 | |
97979ddf JS |
876 | <P><LI>More about naming conventions</LI><P> |
877 | <OL> | |
878 | <P><LI><A NAME="wx_prefix"></LI><B>Use wx or WX prefix for all public symbols</B>. | |
879 | wx should be used for functions and classes, WX for macros. | |
172d3acb | 880 | <P><LI><A NAME="wxdllexport"</LI><B>Use WXDLLEXPORT with all classes/functions in |
97979ddf JS |
881 | wxMSW/common code</B> |
882 | The title says it all - every public (in the sense that it is not internal to | |
883 | the library) function or class should have WXDLLEXPORT macro in its | |
884 | declaration to allow compilation of wxWindows as shared library. For example:<P> | |
885 | ||
886 | <pre> | |
887 | bool WXDLLEXPORT wxYield(void); | |
888 | class WXDLLEXPORT MyClass; // (for forward declarations and real declarations) | |
889 | WXDLLEXPORT_DATA(extern wxApp*) wxTheApp; | |
890 | </pre> | |
891 | ||
892 | The reason for the strange syntax for data is that some compilers use different | |
893 | keyword ordering for exporting data. | |
894 | ||
97979ddf | 895 | <P><LI><A NAME="set_get"></LI><B>Use Set/Get prefixes for accessors</B><P> |
172d3acb VZ |
896 | There is a convention in wxWindows to prefix the accessors (i.e. any simple, in |
897 | general, inline function which does nothing else except changing or returning | |
97979ddf | 898 | the value of a member variable) with either <TT>Set</TT> or <TT>Get</TT>. |
172d3acb VZ |
899 | |
900 | <P><LI><A NAME="constants"></LI><B>wxNAMING_CONSTANTS</B><P> | |
901 | The constants in wxWindows code should be defined using <TT>enum</TT> C++ | |
902 | keyword (and not with <TT>#define</TT> or <TT>static const int</TT>). They | |
903 | should be declared in the global scope (and not inside class declaration) and | |
904 | their names should start with a <TT>wx</TT> prefix. Finally, the constants | |
905 | should be in all capital letters (except the first 2) to make it easier to | |
906 | distinguish them from the variables with underscores separating the words. | |
907 | ||
908 | <P>For example, file-related constants should be declared like this: | |
909 | <pre> | |
910 | enum | |
911 | { | |
912 | wxFILEOPEN_READ, | |
913 | wxFILEOPEN_WRITE, | |
914 | wxFILEOPEN_READWRITE | |
915 | }; | |
916 | </pre> | |
917 | ||
97979ddf JS |
918 | </OL> |
919 | ||
920 | <P><LI>Miscellaneous</LI><P> | |
921 | <OL> | |
922 | <P><LI><A NAME="forward_decl"></LI><B>Use forward declarations whenever possible</B><P> | |
923 | It's really a trivial piece of advice, but remember that using forward declarations | |
924 | instead of including the header of corresponding class is better because not | |
925 | only does it minimize the compile time, it also simplifies the dependencies | |
926 | between different source files. | |
172d3acb | 927 | <P>On a related subject, in general, you should try not to include other |
97979ddf JS |
928 | headers from a header file. |
929 | ||
930 | <P><LI><A NAME="debug_macros"></LI><B>Use debugging macros</B><P> | |
931 | wxWindows provides the debugging macros <TT>wxASSERT, wxFAIL</TT> and | |
932 | <TT>wxCHECK_RET</TT> in <TT><wx/wx.h></TT> file. Please use them as often as | |
933 | you can - they will never do you any harm but can greatly simplify the bug | |
934 | tracking both for you and for others. | |
935 | <P>Also, please use <TT>wxFAIL_MSG("not implemented")</TT> instead of writing | |
936 | stubs for not (yet) implemented functions which silently return incorrect | |
937 | values - otherwise, a person using a not implemented function has no idea that | |
938 | it is, in fact, not implemented. | |
939 | <P>As all debugging macros only do something useful if the symbol | |
172d3acb | 940 | <TT>__WXDEBUG__</TT> is defined, you should compile your programs in debug mode to profit |
97979ddf JS |
941 | from them. |
942 | </OL> | |
943 | </UL> | |
944 | ||
945 | <P> | |
946 | ||
947 | <HR> | |
948 | Please send any comments to <A HREF=mailto:zeitlin@dptmaths.ens-cachan.fr>Vadim Zeitlin</A>. | |
949 | ||
950 | </font> | |
951 | ||
952 | </BODY> | |
953 | </HTML> |