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