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