|
1 Galadriel coding style |
|
2 |
|
3 Lluís Batlle i Rossell |
|
4 viric@vicerveza.homeunix.net |
|
5 |
|
6 Iniciat el 11/08/2003 |
|
7 |
|
8 |
|
9 Aquest és un petit document que descriu l'estil d'escriptura de codi pel |
|
10 projecte Galadriel. L'estil d'escriptura és molt personal, i no s'han de forçar |
|
11 aquestes idees sobre ningú, però ja que és una cosa que hem de mantenir entre |
|
12 tots, seria bo que l'estil no ens dificultés aquesta feina. Així que, si més no, |
|
13 tingueu en compte els punts que aquí es mencionen. |
|
14 |
|
15 Aquest document no està ni revisat ni acabat. En alguns llocs hi ha comentaris |
|
16 de la forma (MAJUSCULES ?!), que significa que no sé què posar-hi, i algú de |
|
17 vosaltres segur que ho sabrà millor i abans que jo. |
|
18 |
|
19 Aquest document també està molt influenciat per la guia de Linus Torvalds: |
|
20 "Linux kernel coding style". El google us donarà la referència a aquest escrit. |
|
21 |
|
22 Espero comentaris ben aviat... |
|
23 |
|
24 |
|
25 1. Indentació (sagnat) |
|
26 |
|
27 Els tabuladors estan pensats per ser d'una longitud de 8 caràcters. Si volem |
|
28 respectar a la resta de món, aquest és l'esquema que hauriem de seguir. Però |
|
29 segur que s'aixecarà protestant molta gent si pretenem tabulacions d'aquesta |
|
30 mida. Això és perquè molta gent troba excessius 8 caràcters per a indentar; bé, |
|
31 indentar serveix per diferenciar quan comença i acaba un bloc de control, així |
|
32 que si fem indentacions grans diferenciarem molt més aquests blocs, sobretot |
|
33 quan alguns de nosaltres portem més de 15 hores davant de codi. |
|
34 |
|
35 Molts direu, tot i això, que 8 caràcters és una indentació massa gran, i que |
|
36 mouen el codi massa cap a la dreta... bé, tal com diu el senyor Torvalds, "if |
|
37 you need more than 3 levels of indentation, you're screwed anyway, and should |
|
38 fix your program". Això vol dir que utilitzar 8 caràcters també ens dóna una |
|
39 idea de quant bo és el nostre codi. |
|
40 |
|
41 Fer servir tabuladors de menys de 8 caràcters també porta problemes entre |
|
42 editors... sobretot per discernir quan s'indenta amb tabuladors o bé amb espais. |
|
43 |
|
44 De tota manera, podem justificar l'ús d'indentacions més petites perquè no és el |
|
45 mateix escriure en C++ que amb C; sembla una excusa, però és amb l'únic que ens |
|
46 podem recolzar. Queda doncs establert, tal com es va decidir a l'explicació d'en |
|
47 Shadow el dissabte, que s'utilitzarà indentació amb espais de 3 caràcters. |
|
48 |
|
49 |
|
50 2. Ample de pantalla |
|
51 |
|
52 Molts utilitzem GUIs per escriure el nostre codi, i el fet d'estar allunyat de |
|
53 l'antic mode de 80x25, tenir resolucions més grans i fonts més petites ens ha |
|
54 permès arribar a pantalles de 170x60. De tota manera, tot i que ens pensem que |
|
55 la majoria de gent ja utilitza resolucions superiors a 1024x768, no és bo |
|
56 imposar als programadors la nostra manera d'escriure codi. Encara són molts els |
|
57 que programen en 80x25, més que res perquè són les dimensions dels terminals més |
|
58 comuns. Són amb la que els terminals VT servien les lletres més grans |
|
59 (ideals per programadors cansats), les que ens dóna la BIOS abans de l'arrencada |
|
60 del sistema, i la de la majoria d'emuladors de terminal de X. A més a més, |
|
61 facilita molt el tenir diferents porcions de codi a la pantalla alhora. I donat |
|
62 que suposem que tothom disposa de monitors de diagonal poc superior a 14", les |
|
63 mides de caràcter no són massa petites per passar llargues hores davant la |
|
64 pantalla. |
|
65 |
|
66 |
|
67 3. Claus {} |
|
68 |
|
69 Un altre assumpte que sol portar confusions i incomoditats només perquè hi ha |
|
70 diferents estils d'escriptura de codi és la col·locació de les claus d'inici i |
|
71 fi de bloc. Seguint les indicacions de Kernighan i Ritchie, l'estil preferit és |
|
72 el de posar la clau d'obertura a final de línia, i la de tancament indentada a |
|
73 la mateixa columna que el que ha iniciat el bloc: |
|
74 |
|
75 if (x == 1) { |
|
76 printf("Hola"); |
|
77 } |
|
78 |
|
79 Tot i això hi ha un cas especial, les funcions. Tenen la clau d'obertura a |
|
80 l'inici de la següent línia, així: |
|
81 |
|
82 int funcio(int x) |
|
83 { |
|
84 return 2*x; |
|
85 } |
|
86 |
|
87 A molts no ens agrada aquesta aquesta inconsistència, però té una justificació: |
|
88 les funcions no es poden aniuar. El fet d'utilitzar sempre l'obertura de clau a |
|
89 la pròxima línia també fa que en aquesta línia no hi hagi res més escrit mai, i |
|
90 porta a problemes de lectura, com en els casos: |
|
91 |
|
92 do |
|
93 { |
|
94 printf( "%i\n", i ); |
|
95 } |
|
96 while( i < 10 ); |
|
97 |
|
98 o bé, |
|
99 |
|
100 if( i > 10 ) |
|
101 { |
|
102 printf( "i gran\n" ); |
|
103 } |
|
104 else |
|
105 { |
|
106 printf( "i petita\n" ); |
|
107 } |
|
108 |
|
109 coses que evidentment queden molt més clares així: |
|
110 |
|
111 do { |
|
112 printf( "%i\n", i ); |
|
113 } while( i < 10 ); |
|
114 |
|
115 o bé |
|
116 |
|
117 if( i > 10 ) { |
|
118 printf( "i gran\n" ); |
|
119 } else { |
|
120 printf( "i petita\n" ); |
|
121 } |
|
122 |
|
123 El més important és que no quedin línies buides, ja que hem de pensar en les 25 |
|
124 línies, a part de les 80 columnes. Al deixar menys línies buides permet |
|
125 reaprofitar aquestes línies de pantalla que no perdem per a afegir comentaris. |
|
126 |
|
127 |
|
128 4. Espaiat d'expressions |
|
129 |
|
130 Les expressions poden arribar a ser molt críptiques si no estan ben espaiades (o |
|
131 gens). Per tant, adoptarem la regla general de posar un espai entre cada valor |
|
132 (immediat o variable) i el seu operador binari, i no posar cap espai entre un |
|
133 operador unari i el valor a què afecta. Si les variables no fan servir caràcters |
|
134 més enllà dels alfanumèrics, això no hauria de suposar cap problema de lectura. |
|
135 |
|
136 El pas de paràmetres en una crida a una funció, així com a la seva definició, es |
|
137 farà enganxant el parèntesi d'obertura al nom de la funció, i els paràmetres el |
|
138 seguiran començant amb un espai de separació entre aquest parèntesi i el primer, |
|
139 i els següents aniran succeint com si d'un text redactat es tractés. Entre |
|
140 l'últim paràmetre i el parèntesi de tancament hi haurà, com en l'obertura, un |
|
141 espai de separació. |
|
142 |
|
143 En el cas de no haver-hi paràmetres, podem utilitzar () enganxat al nom de la |
|
144 funció. |
|
145 |
|
146 |
|
147 5. Definició de variables |
|
148 |
|
149 Alguns caràcters especials defineixen variables com a punters o referències als |
|
150 tipus de dades amb què les declarem. Considerarem que aquests caràcters no són |
|
151 operadors unaris, i són una dada més alhora de definir el paràmetre. Per tant, |
|
152 s'escriuran un espai després del tipus de dades a què apunten o referencien, i |
|
153 separats tans espais com calgui del nom de la variable (en el cas que alineem |
|
154 definicions). Això s'aplicarà tan al cos de les funcions com a la declaració |
|
155 dels seus paràmetres o valors de retorn. |
|
156 |
|
157 |
|
158 6. Nomenclatura |
|
159 |
|
160 Queda clar que totes les funcions i variables han de tenir noms clarament |
|
161 descriptius. Això sol implicar que aquests noms estiguin composats de més d'una |
|
162 paraula. Seguint l'estil dels de QT, utilitzarem la tècnica de que les paraules |
|
163 que composen el nom d'una class comencen totes amb majúscula (Amb una G |
|
164 majúscula de Galadriel a davant en el codi del kernel). Els mètodes |
|
165 s'escriuran igual que les classes, però amb la lletra de la primera paraula en |
|
166 minúscula. Les variables, igual que els mètodes (moltes vegades, en programació |
|
167 a objectes, no sabem si referenciem a mètodes o a variables. Això ha de |
|
168 mantenir-se transparent). |
|
169 |
|
170 class Tree |
|
171 { |
|
172 int * firstLeaf; |
|
173 |
|
174 public: |
|
175 void addLeaf(); |
|
176 }; |
|
177 |
|
178 En el cas de parlar de comptadors o altres estructures de codi en què l'ús de |
|
179 les variables queda molt clar, podem utilitzar variables d'una sola lletra (i, |
|
180 j, k, ...), preferiblement comptant per la i i sempre en minúscula. |
|
181 |
|
182 En implementar algoritmes matemàtics també podem utilitzar variables d'una sola |
|
183 lletra sempre i quan hi hagi un extens comentari amb el codi expressat |
|
184 matemàticament. |
|
185 |
|
186 |
|
187 7. Classes i estructures |
|
188 |
|
189 Entenem l'idea de Classe amb C++ com a una definició d'objectes que conté |
|
190 variables i -indispensablement- mètodes. Si ens trobem davant del típic ús de C |
|
191 d'una 'struct', ho declararem com a 'struct'. Queda despreciada l'estructura: |
|
192 |
|
193 class MyClass |
|
194 { |
|
195 public: |
|
196 int a; |
|
197 int b; |
|
198 int * c; |
|
199 } |
|
200 |
|
201 Evidentment, només utilitzarem aquest concepte d'estructura si la idea d'una |
|
202 "classe amb els seus mètodes" fa complicat l'ús d'aquestes dades. També hem de |
|
203 preveure si farà o no falta una futura encapsulació; en aquest cas declararem |
|
204 una classe amb mètodes senzills. |
|
205 |
|
206 El tipus de definicions (public, protected o private, així com slots i signals) |
|
207 es faran al nivell d'indentació de la funció, ja que la indentació serveix per |
|
208 indicar 'blocs', i això és el que volem aquí. Podem utilitzar vàris entorns de |
|
209 public, protected o private per afegir claredat a la definició de la classe, |
|
210 utilitzant-los de separadors en les definicions de membres. |
|
211 |
|
212 Quan declarem una classe també espaiarem el nom de la classe, els |
|
213 dobles dos punts i el nom del mètode. Igualment amb l'herència en la definició |
|
214 de classes i en la crida a constructors de la mare. |
|
215 |
|
216 |
|
217 8. Mètodes senzills |
|
218 |
|
219 És fàcil trobar-nos amb mètodes (i sobretot constructors) que simplement |
|
220 assignen els valors dels paràmetres a variables privades de la classe. Per |
|
221 evitar codi redundant, utilitzarem el mètode ja disponible en C i que s'ha |
|
222 arrossegat fins a la crida de constructors de classes mare. Així que |
|
223 utilitzarem: |
|
224 |
|
225 void MyClass :: Constructor( int _myVar ) |
|
226 : mother( _myVar ), classVar( _myVar ), |
|
227 { |
|
228 //.... codi (si cal!).... |
|
229 } |
|
230 |
|
231 Aquestes declaracions es poden fer fins i tot (preferiblement) -inline- dins |
|
232 la definició de la classe. |
|
233 |
|
234 La nomenclatura dels paràmetres de mètodes d'aquest tipus es farà utilitzant |
|
235 exactament el mateix nom que la variable interna, fet amb què s'evitarà |
|
236 utilitzar caràcters no alfanumèrics en la definició de variables (o altres |
|
237 invents) i s'aconseguirà l'ús de l'estructura anterior. En qualsevol altre cas, |
|
238 s'utilitzaran recursos de 'namespace' per diferenciarles (que és el que realment |
|
239 fem mentalment quan llegim codi que no compleix això). |
|
240 |
|
241 |
|
242 9. Funcions |
|
243 |
|
244 Igual que amb l'indentació, hem d'evitar les funcions amb molts de paràmetres, |
|
245 ja que la definició i les crides ocuparien moltes columnes. |
|
246 Això significa que la funció és molt complexa; s'ha de derivar en funcions més |
|
247 senzilles. Qualsevol ha de poder entendre una funció pel seu nom, i qualsevol |
|
248 funció ha de ser prou senzilla com per ser reutilitzada al màxim. En casos en |
|
249 què necessitem un codi molt ràpid, podem demanar al compilador que ens posi les |
|
250 funcions 'inline'. |
|
251 |
|
252 Una funció ha de ser prou senzilla com per tenir poques variables locals. Masses |
|
253 variables locals indiquen que estem fent una funció que fa masses coses. Hem de |
|
254 tenir en compte que una funció és una cosa que el nostre cap ha de poder |
|
255 entendre al 100% en un mateix instant; no val a haver d'entendre el codi d'una |
|
256 funció per parts. El límit de variables locals el posa el nostre cervell. |
|
257 A més, sempre ens ho hem d'imaginar amb la perspectiva amb què veiem un codi fet |
|
258 fa dues setmanes, no amb la del moment d'escriure'l. |
|
259 |
|
260 |
|
261 10. Comentaris |
|
262 |
|
263 És molt bo que hi hi hagi comentaris en el que escrivim, sobretot per |
|
264 ajudar-nos a entendre què fa un tall de codi. Això és molt important si volem |
|
265 agafar una idea de com resol un problema una funció, sense haver d'entendre al |
|
266 100% com ho fa. |
|
267 |
|
268 És molt típic el problema de posar més comentaris del compte, sobretot en |
|
269 programadors novells. Només s'ha de tenir en compte una regla: no expliqueu COM |
|
270 resol el problema el vostre tall de codi. Simplement expliqueu QUÈ resol, o fins |
|
271 i tot doneu una referència a un mètode conegut. Però sobretot, no expliqueu mai |
|
272 COM ho feu. El codi ha de ser prou bo com perquè el que vulgui saber COM es fa, |
|
273 ho entengui llegint-lo. |
|
274 |
|
275 (MANIES DE FER LLARGS SEPARADORS HORITZONTALS ENTRE COSES !? ) |
|
276 (CAPÇALERES DE FITXERS, GPL, ... ) |
|
277 |
|
278 |
|
279 11. Definicions i doxygen |
|
280 |
|
281 Tots els comentaris del doxygen (així com els comentaris de mètodes, variables, |
|
282 funcions, classes i enumeracions) estaran a les definicions o prototipus. |
|
283 Aquests seran els més restrictius; inclouran els paràmetres per defecte, i |
|
284 altres informacions sobre les funcions: virtuals, estàtiques, constants... |
|
285 |
|
286 Tots els mètodes que siguin correctes en un objecte constant, ho indicaran. Les |
|
287 definicions dels que siguin reimplementables en herència, indicaran virtualitat. |
|
288 I les que no depenguin de les dades, indicaran estàtica. |
|
289 |
|
290 (EXPLICIT ?) |
|
291 |
|
292 Tots els mètodes i variables que puguin ser utilitzats en herència, seran |
|
293 declarats sota 'protected' en comptes de 'private' |
|
294 (possiblement serà en la majoria de casos). |
|
295 |
|
296 |
|
297 12. Encoding |
|
298 |
|
299 Tot el codi que escrivim ha d'estar en ASCII. |
|
300 Això significa oblidar els accents i caràcters per l'estil. De tota manera, de |
|
301 moment podem ser menys restrictius en els comentaris i les sortides de texte; en |
|
302 aquest cas utilitzarem ISO-8859-1 (aka Latin1), i totes les sortides de texte |
|
303 aniran dins del pertinent mètode estàtic 'tr' de QObject (mirar docs de QT). |