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