sarnold |
Welkom
iedereen op de derde dag van Umeet > -) |
sarnold |
onze
eerste spreker vandaag is gregkh, al sinds lang een kernel hacker |
gregkh |
een lange
tijd? ik ben niet _zo_ oud > -) |
sarnold |
hij onderhoudt
de USB stack van de kernel al sinds...1.5 jaar? en hij werkt al veel langer
voor het IBM's linux technology center als ik me goed herinner |
sarnold |
gregkh
gaat spreken over de codeerstijl van de kernel. het valt op dat mensen die
drivers schrijven voor de kernel het op een of andere manier verknallen >
-) |
sarnold |
je hebt
een kind > -) ik denk dat dat je oud maakt > -) |
sarnold |
hoe dan
ook, graag verwelkomen we gregkh > -) |
gregkh |
hehe,
goed punt > -) |
gregkh |
ik ben
hier om iets te vertellen over de goede kernel codeer stijl |
gregkh |
ik ga
een paar redenen overlopen waarom we een richtlijnen hebben betreffende codeerstijlen |
gregkh |
dan vertel
ik iets over de huidige richtlijnen |
gregkh |
en daarna
nog iets over de niet gedocumenteerde richtlijnen die iedereen zou moeten
volgen. |
gregkh |
stel
gerust maar vragen op #qc |
gregkh |
ten eerste,
waarom hebben we codeerrichtlijnen? |
gregkh |
want,
de opmaak van code heeft geen enkele invloed op geheugengebruik, uitvoeringssnelheid, |
gregkh |
of iets
anders wat de gebruiker van de kernel zou kunnen opvallen |
gregkh |
|
gregkh |
de belangrijkste
reden is dat wanneer een grote hoeveelheid code is geschreven in een zelfde
stijl |
gregkh |
het een
direct gevolg heeft op de snelheid waarmee je de code kan verstaan |
gregkh |
je ze
kan nagaan en ze verbeteren. En omdat de linux kernel code bedoelt is |
gregkh |
zodat
anderen ze kunnen aanpassen willen we dat dit zo eenvoudig mogelijk te doen
is |
gregkh |
|
gregkh |
er is
veel onderzoek geweest rond dit onderwerp en mensen kunnen me offline contacteren
voor referenties |
gregkh |
|
gregkh |
ik ben
nogal vlotjes over de redenen aan het gaan waarom we regels nodig hebben,
zijn er hier vragen over? |
gregkh |
ok, geen
excuses dus meer als iemand ze niet volgt > -) |
gregkh |
|
gregkh |
Wat zijn
nu de kernel code opmaak regels? |
gregkh |
ten eerste,
lees de Documentation/CodingStyle in de kernel tree |
gregkh |
het somt
een aantal regels op die _altijd_ gevolgd moeten worden |
gregkh |
vraag> zijn
die regels er omdat Linus ze wilt of zijn ze op iets anders gebaseerd |
gregkh |
ze zijn
op beide gebaseerd, Linus wil het op die manier en het is ook historisch
gegroeid |
gregkh |
een combinatie
van beide dus |
gregkh |
ik ga
de opmaak regels hier samenvatten/opsommen> |
gregkh |
- alle
tabs moeten 8 karakters zijn en het [TAB] karakter moet gebruikt worden in
plaats van spaties |
gregkh |
als je
code hierdoor buiten de rechterkant van je venster komt |
gregkh |
wil dit
zeggen dat je de structuur van je code moet verbeteren |
gregkh |
let er
voor op dat je editor tabs niet vertaald naar spaties, ik heb dat veel zien
gebeuren. |
gregkh |
|
gregkh |
- bij
het gebruik van haakjes moet het openend haakje als laatste op een lijn komen
en het sluitende haakje als eerste op een lijn |
gregkh |
bij voorbeeld |
gregkh |
if (x
is true) { |
gregkh |
we do
y |
gregkh |
} |
gregkh |
de enige
uitzondering hierop zijn functies, deze hebben hun openend |
gregkh |
haakje
op het begin van de lijn zoals > |
gregkh |
in function(int
x) |
gregkh |
{ |
gregkh |
body of
function |
gregkh |
} |
gregkh |
opmerking> en
class als je C++ gebruikt veronderstel ik |
gregkh |
er zit
geen C++ in de kernel > -) |
gregkh |
als je
een bestand wil converteren naar de codeer stijl, kijk eens naar |
gregkh |
scripts/Lindent
in de kernel tree. het is ook een goed begin om uit te zoeken |
gregkh |
hoe indent(1)
en zijn command line argumenten kunnen helpen om de goed codeer stijl te
vinden |
gregkh |
|
gregkh |
vragen
rond indentering en tabs ? |
gregkh |
er zijn
veel slechte voorbeelden hiervan in de kernel, maar daar ga ik niet te diep
op ingaan |
gregkh |
vraag> hoe
breek ik een lange lijn op de goede manier af? |
gregkh |
"de manier"
om dit te doen bestaat niet, zorg er gewoon voor dat het zin heeft. indent(1)
kan een paar verschrikkelijke dingen veroorzaken wat dit betreft. het beste
is dat je later met de hand alles nog eens nagaat. |
gregkh |
vraag> hoe
verplicht zijn deze regels? |
gregkh |
heel
erg verplicht, je patch zal geweigerd worden |
gregkh |
ok, we
gaan verder |
gregkh |
- variabelen
en functie namen moeten beschrijvend genoeg zijn maar ook duidelijk |
gregkh |
geen
lange namen zoals CommandAllocationGroupSize of DAC960_V1_EnableMemoryMailboxInterface(), |
gregkh |
maar
in plaats daarvan, noem ze cmd_group_size of enable_mem_mailbox() |
gregkh |
gemengde
namen zijn niet echt gewenst |
gregkh |
en het
type van de variabele coderen (zoals "hongaarse notatie") is verboden |
gregkh |
vraag> hoe
zit het met patches om de codeerstijl van oude drivers te verbetern |
gregkh |
door
sommige mensen wordt dit aanvaard |
gregkh |
maar
sommige maintainers zijn zeer koppig en willen hun codeerstijl niet veranderen,
negeer ze > ) |
gregkh |
volgende
onderwerp |
gregkh |
- Functies
mogen maar een ding doen en dat ook goed doen |
gregkh |
ze moeten
kort zijn, en maximaal een of twee schermen tekst mogen bevatten |
gregkh |
nu, deze
wordt amper gevolgd maar alstublieft, probeer het toch te volgen |
gregkh |
het zal
het onderhoud van je code na verloop van tijd makkelijker maken |
gregkh |
- commentaar
is zeer goed maar het moet zinvolle commentaar zijn |
gregkh |
slechte
commentaar vertelt hoe code werkt, wie een bepaalde functie schreef, op welke
dag |
gregkh |
en andere
nutteloze dingen. goede commentaar legt uit |
gregkh |
wat het
bestand of functie doet en waarom het dat doet. |
gregkh |
als je
commentaar voor functies gaat schrijven, gebruik het kerneldoc formaat |
gregkh |
dit staat
uitgelegd in Documentation/kernel-doc-nano-HOWTO.txt en |
gregkh |
scripts/kernel-doc
files in de kernel tree. |
gregkh |
dit laat
toe om automatisch documentatie te laten genereren voor je code |
gregkh |
- en
de laatste geschreven regel |
gregkh |
reference
count je data structuren |
gregkh |
dit is
niet echte stijl richtlijn maar wel een codeer richtlijn |
gregkh |
als een
andere thread je data structuur kan vinden en je hebt geen |
gregkh |
reference
count naar de data structur, heb je bijna zeker een bug |
gregkh |
de kernel
heeft nu een kobject structuur die gemakkelijk gebruikt kan worden |
gregkh |
als je
een reference count nodig hebt in je structuur |
gregkh |
vragen
over de gedocumenteerde regels? |
gregkh |
vraag> wat
met de uniekheid van de verschillende functie namen in de code |
gregkh |
wat bedoel
je met "uniekheid" ? |
gregkh |
bedoel
je "global namespace"? |
gregkh |
ja, kies
je functienamen goed en maak ze niet nutteloos globaal, enkel als het echt
moet |
gregkh |
ok, we
gaan nu over naar de ongeschreven regels |
gregkh |
- gebruik
code die al geschreven is |
gregkh |
gebruik
de lijst structuur, string structuur, de kobject structuur |
gregkh |
de endian
functies en andere, reeds geschreven en gedebugged in je kernel |
gregkh |
dupliceer
GEEN code juist omdat je een library functie wil gebruiken |
gregkh |
ze zijn
daar voor een reden |
gregkh |
om over
te gaan naar mijn volgende regel> |
(vertaler> niet vertaald om de expressiviteit
van de spreker weer te geven > -) ) |
- typedef is EVIL! |
gregkh |
EVIL EVIL EVIL EVIL EVIL! |
gregkh |
NEVER USE typedef IN YOUR CODE!!! |
gregkh |
got it? > ) |
gregkh |
zelfs
al ben je Ingo, langzaam aan is ook hij aan het veranderen > -) |
gregkh |
enkel
in _zeer_ zeldzame gevallen moet je een typedef maken |
gregkh |
een functiepointer
is een van die gevallen |
gregkh |
vraag> waarom
is dat zo evil |
gregkh |
het verstopt
informatie voor de programmeur en stelt ze in staat domme dingen te doen |
gregkh |
zoals
een een ganse structuur op de stack zetten als parameter en andere onzin |
gregkh |
opniew,
typedefs voor functiepointers ijn ok |
gregkh |
maar
dat is het echt wel |
gregkh |
als je
maar een "ongeschreven" regel gaat herinneren, laat het deze zijn |
gregkh |
ik ga
even wachten zodat de vertalers kunnen volgen, sorry om zo snel te typen |
gregkh |
vraag> wat
is er slecht met het doorgeven van structuren als parameters |
gregkh |
geef
een pointer door naar de structuur, niet de structuur zelf, die neemt teveel
plaats op de stack en is zeer traag |
gregkh |
ok, we
gaan door |
gregkh |
-
plaats geen "magic numbers" in je code |
gregkh |
als je
numerieke waarden wil gaan gebruiken, documenteer het en maak er een |
gregkh |
#define
van zodat anderen begrijpen wat je wil doen |
gregkh |
als het
een waarde is die de gebruiker ooit zou willen veranderen, maak er een sysctl
waarde van, een command line optie of een module parameter optie |
gregkh |
-
plaats geen #ifdef in een .c bestand |
gregkh |
deze
zijn enkel toegelaten in .h bestanden |
gregkh |
gebruik
de preprocessor om code weg te compilen die niet in de configuratie zit,
gebruik geen |
gregkh |
#ifdef
in de code om dit te doen |
gregkh |
zijn
hier vragen over? |
gregkh |
vraag> maar
wat met #ifdef CONFIG_SMP in mm/slab.c bijvoorbeeld |
gregkh |
ja, op
sommige plaatsen kunnen we niet anders maar in het algemeen> gebruik
het niet |
gregkh |
vergeet
ook niet, deze regels zijn enkel richtlijnen, je zal plaatsen vinden waar
ze allemaal gebroken worden, maar probeer ze toch in 99% van de code te volgen |
gregkh |
een laatste
ongeschreven regel, gebruik labeled indentifiers voor structuren die je initialiseert
tijdens het compileren |
gregkh |
en daarmee
bedoel ik het volgende> |
gregkh |
struct
foo bar = { |
gregkh |
.a
= 24, |
gregkh |
.b
= 42, |
gregkh |
}; |
gregkh |
gebruik
de C99 stijl initializers en niet de gnu style, mensen gaan momenteel de
gehele kernel af |
gregkh |
om ze
te converteren |
gregkh |
om te
concluderen> |
gregkh |
-
lees read Documenatation/CodingStyle |
gregkh |
-
volg het |
gregkh |
-
gebruik scripts/Lindent. |
gregkh |
-
gebruik geen typedef |
gregkh |
verdere
vragen? |
gregkh |
vraag> hoe
vermijd ik #ifdef CONFIG_MYOPTION in praktijk (heb je een voorbeeld?] |
gregkh |
bijvoorbeeld,
kijk naar include/linux/hiddev.h en drivers/usb/input/hid_core.c voor sommige
functies |
gregkh |
die weggecompileerd
worden als #ifdef CONFIG_USB_HIDDEV niet aan staat |
gregkh |
ik heb
een langere paper hierover die gepresenteerd op ols2002 en die zich hier
bevindt> http> //www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_paper/codingstyle.ps |
gregkh |
en enkele
slides op http> //www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ |
gregkh |
vraag> is
het beter om de .c bestanden te splitsen? |
gregkh |
nee,
splits de functies en gebruik static inline functies die niets doen wanneer
de configuratie optie niet geselecteerd is |
gregkh |
roep
ze dan op in het .c bestand, gcc zal ze wegcompileren als de configuratie
niet aanstaat |
gregkh |
kijk
ook eens naar include/security.h in de 2.5.51 kernel, het heeft veel voorbeelden
hiervan als CONFIG_SECURITY niet aanstaat |
gregkh |
vraag> dus,
gebruik makende van een functie waarvan de inhoud gewist wordt met een #ifdef |
gregkh |
op een
manier wel, kijk naar bovenstaande voorbeelden voor de werking |
gregkh |
dat is
het, andere vragen? als er iemand later vragen heeft, mail me. |
(applaus en einde presentatie) |