%% Documentation/CodingStyle and beyond... %% last modified 2002_06_18 %% Greg Kroah-Hartman %% %% %% Released under the GNU FDL %% %% use our own settings %%deffont "standard" tfont "standard.ttf", tmfont "kochi-mincho.ttf" %%deffont "thick" tfont "thick.ttf", tmfont "goth.ttf" %%deffont "typewriter" tfont "typewriter.ttf", tmfont "goth.ttf" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Default settings per each line numbers. %% %%default 1 leftfill, size 2, fore "white", back "black", font "thick" %%default 2 size 7, vgap 10, prefix " " %%default 3 size 2, bar "gray70", vgap 10 %%default 4 size 5, fore "white", vgap 30, prefix " ", font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Default settings that are applied to TAB-indented lines. %% #%tab 1 size 5, vgap 40, prefix " ", icon box "green" 50 %%tab 1 size 5, vgap 40, prefix " ", icon arc "green" 40 %%tab 2 size 4, vgap 40, prefix " ", icon arc "yellow" 50 %%tab 3 size 3.5, vgap 40, prefix " ", icon delta3 "white" 40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% use our own settings #%deffont "standard" tfont "standard.ttf", tmfont "kochi-mincho.ttf" #%deffont "thick" tfont "thick.ttf", tmfont "goth.ttf" #%deffont "typewriter" tfont "typewriter.ttf", tmfont "goth.ttf" #%deffont "typewriter" xfont "monospace:bold" %deffont "typewriter" xfont "bitstream vera sans mono:bold" %deffont "email" xfont "bitstream vera sans mono" #%deffont "typewriter" xfont "bitstream sans mono" %deffont "standard" xfont "bitstream charter" #%deffont "standard" xfont "P22 Typewriter" #%deffont "standard" xfont "bitstream vera sans" #%deffont "standard" xfont "monospace" %deffont "title" xfont "P22 Typewriter" #%deffont "thick" xfont "bitstream vera sans:bold" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Default settings per each line numbers. %% %default 1 leftfill, size 1, fore "black", back "white" %default 2 size 10, vgap 10, prefix " ", fore "black", font "title" #%default 3 size 2, bar "gray70", vgap 10, fore "black" %default 3 size 2, bar "steel blue", vgap 10, fore "black" %default 4 size 8, fore "white", vgap 10, prefix " ", font "standard", fore "black" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Default settings that are applied to TAB-indented lines. %% #%tab 1 size 5, vgap 40, prefix " ", icon box "green" 50 %tab 1 size 7.5, vgap 20, prefix " ", icon arc "steel blue" 40 %tab 2 size 6.0, vgap 20, prefix " ", icon arc "sea green" 50 %tab 3 size 4.5, vgap 20, prefix " ", icon arc "violet red" 40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page %nodefault %fore "black", back "white", center %size 14, font "title" Documentation/CodingStyle %size 15 and beyond... %font "standard" %size 8 Greg Kroah-Hartman %size 6 %font "typewriter" greg@kroah.com www.kroah.com/linux/ %font "standard" SUCON 2004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Disclaimer There is no disclaimer! If your code is used as a bad example, go fix it! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Why care? "Code formatting doesn't matter." "Why is your style better than mine?" "Doesn't affect compiled size." "Doesn't affect execution speed." "K&R style is out of date." %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Proven to matter Soloway & Ehrlich: %size 6.6 "It is not merely a matter of aesthetics that programs should be written in a particular style. Rather there is a psychological basis for writing programs in a conventional manner: programmers have strong expectations that other programmers will follow these discourse rules. If the rules are violated, then the utility afforded by the expectations that programmers have built up over time is effectively nullified." In short, consistency matters. Lots of other research backs this up. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page So what are the rules? %font "typewriter", size 10, center Documentation/CodingStyle %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Indentation Use tabs. All tabs are 8 characters. If your code is indenting too deeply, fix the code. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Indentation - examples Good: %cont, font "typewriter" fs/* %font "standard" %cont, font "typewriter" kernel/* %font "standard" Bad: %cont, font "typewriter" drivers/scsi/eata.c %font "standard" %cont, font "typewriter" drivers/block/DAC960.c %font "standard" mix of correct and incorrect indenting. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Braces Opening brace last on the line. Closing brace first on the line: %font "typewriter", size 5 if (x is true) { we do y } %font "standard" Exception for functions: %font "typewriter", size 5 int function(int x) { body of function } %font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Braces - examples Bad: %cont, font "typewriter" drivers/atm/nicstar.c %font "standard" %font "typewriter", size 4 if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) for (i = 0; i < scq->num_entries; i++) { if (scq->skb[i] != NULL) { vcc = ATM_SKB(scq->skb[i])->vcc; if (vcc->pop != NULL) vcc->pop(vcc, scq->skb[i]); else dev_kfree_skb_any(scq->skb[i]); } } else /* vcc must be != NULL */ { %font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Braces - examples Good: %cont, font "typewriter" kernel/*.c %font "standard" %cont, font "typewriter" drivers/usb/core/* %font "standard" %cont, font "typewriter" drivers/base/* %font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Automatic code fixer %font "typewriter", size 10, center scripts/Lindent %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Variable and Function Naming Be descriptive. Be concise. No MixedCase. No encoding the type within the name. Global variables only when necessary. Local variables short and to the point. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Naming - examples Bad: %cont, font "typewriter" CommandAllocationGroupSize %font "standard" %cont, font "typewriter" DAC960_V1_EnableMemoryMailboxInterface() %font "standard" %cont, font "typewriter" loop_counter %font "standard" %cont, font "typewriter" drivers/bock/DAC960.* %font "standard" Good: %cont, font "typewriter" cmd_group_size %font "standard" %cont, font "typewriter" enable_mem_mailbox() %font "standard" %cont, font "typewriter" i %font "standard" %cont, font "typewriter" fs/*.c %font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Functions Do one thing, and do it well. Short, one or two screens of text. OK to have longer function doing small different things. If more than 10 local variables, too complex. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Functions - examples Bad: %cont, font "typewriter" drivers/pci/hotplug/ibmphp_res.c %font "standard" %cont, font "typewriter" ibmphp_check_resource() %cont, font "standard" has 370 lines %cont, font "typewriter" drivers/usb/serial/usbserial.c %font "standard" %cont, font "typewriter" usb_serial_probe() %cont, font "standard" has 21 local variables Good: %cont, font "typewriter" fs/*.c %font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Exiting functions Exit in only one place Easier to understand and follow Nesting is reduced Harder to create new errors %cont, font "typewriter" goto %cont, font "standard" is your friend %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Comments Good to have, but must be done correctly. Bad comments are worse than no comments. Bad comments: explain how code works say who wrote the function have last modified date have other trivial things %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Comments - Good ones Good comments: explain what explain why should be at beginning of function no more than is absolutely needed %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Comment format Kernel-doc, variant of GNOME-doc Create standalone documentation %cont, font "typewriter" make psdocs %font "standard" %cont, font "typewriter" make htmldocs %font "standard" %cont, font "typewriter" Documentation/kernel-doc-nano-HOWTO.txt %font "standard" %cont, font "typewriter" scripts/kernel-doc %font "standard" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Function Comment %font "typewriter" /** * my_function - does my stuff * @my_arg: my argument * * Does my stuff explained. */ void my_function (int my_arg) { ... } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Structure Comment %font "typewriter", size 7.5 /** * struct my_struct - short description * @a: first member * @b: second member * * Longer description */ struct my_struct { int a; int b; }; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Comments - examples Bad: %cont, font "typewriter" arch/i386/kernel/cpu/mtrr/generic.c %font "standard" mix of old and new style comments %cont, font "typewriter" drivers/scsi/pci2220i.c %font "standard" how to %cont, size 7, fore "red" NOT %cont, size 4.5, fore "black" create function comment blocks Good: %cont, font "typewriter" drivers/usb/core/*.c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Data Structure requirements Use reference counting: %size 10 "If another thread can find your data structure, and you do not have a reference count on it, you almost certainly have a bug." %size 7.5 %cont, font "typewriter" struct kref %font "standard" %cont, font "typewriter" struct kobject %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page No magic numbers A "non-obvious" value that is hard coded Fortunately, not many instances %cont, font "typewriter" drivers/usb/serial/pl2303.c %font "standard" use a %cont, font "typewriter" #define %cont, font "standard" or %cont, font "typewriter" enum %font "standard" should be CAPITALIZED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page inline functions vs. macros inline functions are preferred compile checks the types much harder to mess up %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Unwritten rules Avoid "Not Invented Here": string functions byte order functions linked lists reference counting %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page %nodefault %size 20 %font "typewriter" typedef %cont, size 22, font "standard" is %cont, size 24, fore "red" evil %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page evil evil evil! It hides the real type of the variable. Allows programmers to get into trouble more easily: large structures on the stack large structures passed as return values Can hide long structure definitions: pick a better name %cont, font "typewriter" typedef %cont, font "standard" just to signify a pointer type? could you be lazier? Not in System 6 codebase. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Well, mostly evil Base system types %cont, font "typewriter" u8, u16, u32, u64, %cont, font "standard" etc. %cont, font "typewriter" dev_t %font "standard" %cont, font "typewriter" list_t %font "standard" Function pointers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page typedef - examples Bad: %cont, font "typewriter" include/linux/raid/md*.h %font "standard" every other structure has a typedef assigned to it %cont, font "typewriter" include/linux/ide.h %size 4.5 typedef union { ... } ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Labeled identifiers explained %font "typewriter", size 5.5 struct foo { int a; int b; }; %font "standard" Old way: %font "typewriter", size 5.5 static struct foo bar = {A_INIT, B_INIT}; %font "standard" Labeled way: %font "typewriter", size 5.5 static struct foo bar = { .a = A_INIT, .b = B_INIT, }; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Labeled identifiers Use them in initializers Keeps structure changes from breaking code If a field is not specified, it is set to zero Easier to search for Automatic documentation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Labeled identifiers - examples %cont, font "typewriter" struct file_operations %font "standard" if fields are not set, default VFS operations are used %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Conclusions Read %cont, font "typewriter" Documentation/CodingStyle %cont, font "standard" and follow it. Use %cont, font "typewriter" scripts/Lindent %cont, font "standard" . Do not use %cont, font "typewriter" typedef %cont, font "standard" . %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page %nodefault %fore "black", back "white", center %size 14, font "title" Documentation/CodingStyle %size 15 and beyond... %font "standard" %size 8 Greg Kroah-Hartman %size 6 %font "typewriter" greg@kroah.com www.kroah.com/linux/ %font "standard" SUCON 2004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%