]>
Commit | Line | Data |
---|---|---|
1 | This is just a note explaining the additional coding standards I use in | |
2 | the OS/2 port. These are in addition to the project standards and are designed | |
3 | to enhance the readability and maintenance of the code. There are two main | |
4 | standards I employ and few minor ones. Indentation/columner aligned code | |
5 | and variable naming are the key conventions I use. | |
6 | ||
7 | Indentations allow for a very clean look and feel to the code as well as assisting | |
8 | in debugging. This is really more a stylistic option that just makes the code | |
9 | look better and easier to read. Basically I put the data declaration type to the left | |
10 | and the variable in column 37 or 41 (9 or ten 4 space tabs from the left margin). | |
11 | All indentations are multiples of 4. Probably the most important indentation | |
12 | standard I use concerns if/else constructs. | |
13 | ||
14 | I find code like: | |
15 | ||
16 | if (var == 1) MyFunc(); | |
17 | else return FALSE; | |
18 | ||
19 | and: | |
20 | if (eVal == ENUM1) { | |
21 | DoSomething(); | |
22 | DoSomethingElse(); | |
23 | } else if (eVal == ENUM2) { | |
24 | DoAnotherThing(); | |
25 | DoSomethingElse(); | |
26 | } else return FALSE; | |
27 | ||
28 | to be ugly, hard to match openning and closing braces, and a bit of pain for | |
29 | some debuggers. So I use this instead: | |
30 | ||
31 | if (var == 1) | |
32 | MyFunc(); | |
33 | else | |
34 | return FALSE; | |
35 | ||
36 | and: | |
37 | if (eVal == ENUM1) | |
38 | { | |
39 | DoSomething(); | |
40 | DoSomethingElse(); | |
41 | } | |
42 | else if (eVal == ENUM2) | |
43 | { | |
44 | DoAnotherThing(); | |
45 | DoSomethingElse(); | |
46 | } | |
47 | else | |
48 | return FALSE; | |
49 | ||
50 | This is infinitely more readable, allows for easy matchup of openning and | |
51 | closing braces and is friendlier to debuggers. | |
52 | ||
53 | Another issue in this category is the function call with large number of parameters. | |
54 | Especially if some of the parameters are function calls themselves. I find code | |
55 | like | |
56 | ||
57 | MyCall2( param, someotherparam, CallAnotherProc(), CallYetAnotherProc(), param2, param3, Yourproc(), param4); | |
58 | ||
59 | to be ugly and hard on some debuggers and some editors/printers don't like trailing | |
60 | out over 100 columns. I prefer something like this: | |
61 | ||
62 | MyCall2( param | |
63 | ,someotherparam | |
64 | ,CallAnotherProc() | |
65 | ,CallYetAnotherProc() | |
66 | ,param2 | |
67 | ,param3 | |
68 | ,Yourproc() | |
69 | ,param4 | |
70 | ); | |
71 | ||
72 | Much more readable, and debugger and editor friendly. | |
73 | ||
74 | Like I said above all that is mostly style, but below is something that I find | |
75 | partiuclarly irritating about a lot of code in this and other public projects, | |
76 | the haphazard and lazy use of variable names. How often have you found yourself | |
77 | deep down in a large function and run across something like xd = p or CallProc(val, val2) | |
78 | and you have no idea what xd or p is or where val or val2 are delcared and you | |
79 | have to go spend time to find them? Waste of time. Or something like | |
80 | if (val). Is val an integer you are testing for nonzero or a pointer for nonNULL? | |
81 | You have to back up somewhere or into a class header to find it in order to know. | |
82 | Coders that use one or two character identifiers in anything other than loop | |
83 | controls are basically just lazy. | |
84 | ||
85 | To alleviate a lot of this poor readability I have instuted the following naming | |
86 | conventions in this port. | |
87 | ||
88 | Class data members are alway preceded with a m_. | |
89 | ||
90 | Datatype prefixes are as follows: | |
91 | ||
92 | n -- int, short | |
93 | l -- long, size_t (specific 32 bit integer) | |
94 | ll -- longlong (64 bit integer) | |
95 | f -- float | |
96 | d -- double | |
97 | w -- word | |
98 | dw -- dword | |
99 | h -- handle | |
100 | u -- unsigned | |
101 | c -- char/byte (8 bit) | |
102 | z -- char* string | |
103 | s -- string class string | |
104 | p -- pointer | |
105 | q -- smart (counted) pointer | |
106 | r -- reference | |
107 | a -- array | |
108 | v -- user or library defined datatype (can be a struct, typedef, or even | |
109 | a class variable). | |
110 | ||
111 | So a class member that is a pointer to something is m_pVar. A pointer to an | |
112 | unsigned long is a pulVal. rsVal is a reference to a string. | |
113 | ||
114 | Also I use as many desriptive names as possible. So an int for a box width is | |
115 | nWidth, not w or x. An unsigned long for a datalength is ulLength not len or l. | |
116 | A class member that is a pointer to client window is m_pClient or | |
117 | m_pvClient, not just client. A wxBrush is vBrush or a handle to a brush is | |
118 | hBrush as opposed to br or hbr and if they were class members then m_vBrush and | |
119 | m_hBrush. | |
120 | ||
121 | Some other things you will not find in this port are things like: | |
122 | ||
123 | Large numbers of nested function calls on one line or if statement. | |
124 | ||
125 | Obtuse nonsense like while (*d++ = *s). What is that? Instead you will see | |
126 | ||
127 | while (*d != '\0') | |
128 | { | |
129 | . | |
130 | . | |
131 | . | |
132 | *d++; | |
133 | *d = s; | |
134 | } | |
135 | ||
136 | I hope you will find wxOS2 extremely easy to read, follow, and debug. Unlike | |
137 | a lot of programmers I find writing code to be every bit as much a work of | |
138 | art as of science. The neatness and appearance of one's code tells a every | |
139 | bit as much about the person writing it as its functionality and correctness. | |
140 | ||
141 | Dave Webster, | |
142 | Struggling OS/2 developer. | |
143 | ||
144 |