Dette kapitelet beskriver kildekodestilen foretrukket av LinuxCNC-gjengen.
1. Avstå fra å skade
Når en gjør små endringer i kode som har en annen stil enn den som beskrives under, følg den lokale kodestilen. Rask endring fra en kodestil til en annen reduserer kodens lesbarhet.
Sjekk aldri inn kode etter å ha kjørt «indent» på den. Endringen av blanke tegn introdusert av indent gjør det vanskeligere å følge endringshistorikken i filen.
Ikke bruke et tekstredigeringsprogram som gjør unødvendige endringer i blanke tegn (for eksempel som endrer 8 mellomrom til tabulator pa en linje som ellers ikke blir endret, eller deler linjer som ellers ikke blir endret).
2. Tabulatorstopp
En tabulatorstopp tilsvarer alltid åtte mellomrom. Ikke skriv kode som vises korrekt kun når en bruker en annen tabulatorstoppinnstilling.
3. Innrykk
Bruk 4 mellomrom hvor hvert nivå med innrykk. Det er greit å kombinere 8 mellomrom til et tabulatortegn, men det er ikke påkrevd.
4. Klammeplassering
Plasser åpningsklammen sist på linjen, og plasser avsluttningsklammen først:
if (x) { // gjør noe relevant }
Avslutningsklammen er på en linje for seg selv, unntatt i de tilfeller der den følges av en videreføring av samme uttrykk, som med en «while» i et do-uttrykk eller en «else» i et if-uttrykk, som dette:
do { // noe viktig } while (x > 0);
og
if (x == y) { // gjør en ting } else if (x < y) { // gjør noe annet } else { // gjør en tredje ting }
Denne klammeplasseringen minimerer også antallet blanke (eller neste blanke) linjer, hvilket øker andelen kode eller kommentarer som blir synlig i en terminal med fast størrelse.
5. Navngiving
C er et spartansk språk, og det bør også navngivingen din være. I motsetning til Modula-2- og Pascal-programmører, så bruker ikke C-programmører søte navn som DenneVariabelErEnMidlertidigTeller. En C-programmør ville kalle den variabelen «tmp» som er mye enklere å skrive, og ikke minst vanskeligere å forstå.
Derimot er beskrivende navn for globale variable et krav. Å kalle en global funksjon «foo» fortjener dødsstraff.
GLOBALE variabler (som kun skal brukes hvis du virkelig trenger dem), må ha beskrivende navn, akkurat som globale funksjoner. Hvis du har en funksjon som teller antallet aktive brukere, så bør du kalle den «count_active_users()» eller tilsvarende. Du skal aldri kalle den «cntusr()».
Å bake typen til funksjonen inn i navnet (såkalt hungarsk notasjon), er hjerneskadet - kompilatoren vet typen uansett og kan sjekke dette, og det kun forvirrer programmøren. Ikke rart Microsoft lager programmer fulle av feil.
LOKALE variablenavn bør være korte og presise. Hvis du har en tilfeldig heltallsløkketeller, så bør den antagelig hete «i». Å navngi dem «loop_counter» er ikke-produktivt, da det ikke er noen mulighet for at det kan misforstås. Tilsvarende kan «tmp» hver enhver variabeltype som burkes til å holde på en midertidig verdi.
Hvis du er redd for å blande sammen dine lokale variabelnavn, så har du et annet problem ved navn overproduksjon av funksjonsveksthormon-syndrom. Se neste kapittel.
6. Funksjoner
Funksjoner bør være korte og vakre, og kun gjøre en ting. De bør få plass i en eller to skjermbilder med tekst (ISO/ANSI-skjermstørrelsen er som vi alle vet 80x24), gjøre en ting og gjøre den bra.
Maksimallengden på en funksjon er invers proporsjonal med kompleksiteten og innrykksnivåene til funksjonen. Dermed, hvis du har en konseptuelt enkel funksjon som kun består av et langt (men enkelt) «case»-uttrykk, der du må gjøre mange små steg for en rekke ulike tilfeller, så er det greit å ha en lang funksjon.
Derimot, hvis du har en kompleks funksjon og du mistenker at en mindre begavet førsteårselev på videregående ikke engang er i stand til å forstå hva funksjonen handler om, så bør du begrense deg så mye som mulig til maksimalgrensen. Bruk hjelpefunksjoner med beskrivende navn (du kan be kompilatoren om å bake hjelpefunksjonene inn der de kalles hvis du tror det er kritisk for ytelsen, og den vil antagelig gjøre en bedre jobb der enn du ville klart).
En annen målestokk for funksjonen er antall lokale variabler. Det bør ikke være flere enn 5-10, med mindre du gjør noe galt. Tenk igjennom funksjonen på nytt og del den inn i mindre biter. Menneskehjernen kan generelt sett enkelt holde rede på omtrent 7 ulike ting. Mer enn det og den blir forvirret. Du vet at du selv er brilliant, men det kan hende du kunne tenke deg å forstå hva du gjorde også om to uker.
7. Kommentering
Kommentarer er bra, men det er også en fare for å kommentere for mye. Forsøk ALDRI å forklare hvordan koden din virker i en kommentar. Det er mye bedre å skrive kode slik at hvordan den virker er åpenbart, og det er bortkastet tid å forklare dårlig skrevet kode.
Generally, you want your comments to tell WHAT your code does, not HOW. A boxed comment describing the function, return value, and who calls it placed above the body is good. Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably re-read the Functions section again. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head of the function, telling people what it does, and possibly WHY it does it.
If comments along the lines of /* Fix me */ are used, please, please, say why something needs fixing. When a change has been made to the affected portion of code, either remove the comment, or amend it to indicate a change has been made and needs testing.
8. Skallskript og Makefiler
Ikke alle har de samme verktøy og pakker installert. Noen folk bruker vi, andre emacs, mens noen unngår å ha begge installert og foretrekker et lettvektsprogram som nano eller den innebygget i Midnight Commander for å oppdatere tekster.
gawk versus mawk - Igjen har ikke alle gawk installert, mawk på nesten en tiendel av størrelsen følger også POSIX-standarden. Hvis det trengs en obskur gawk-spesifikk kommando som mawk ikke tilbyr, så vil skriptet ikke virke for noen brukere. Det samme gjelder for mawk. Dermed, bruk generiske awk-kall i stedet for gawk eller mawk.
9. C++-konvensjoner
C++-kodestiler ender ofte opphetede debatter (litt som emacs versus vi-argumenter). En ting er derimot sikkert, en felles stil brukt av alle som jobber i et prosjekt gir enhetlig og lesbar kode.
Naming conventions: Constants either from #defines or enumerations should be in upper case through out. Rationale: Makes it easier to spot compile time constants in the source code, e.g., EMC_MESSAGE_TYPE.
Classes and Namespaces should capitalize the first letter of each word and avoid underscores. Rationale: Identifies classes, constructors and destructors, e.g., GtkWidget.
Metoder (eller funksjonsnavn) bør følge C-anbefalingene over og bør ikke inneholde klassenavnet. Begrunnelse: Gir en felles stil på tvers av C- og C++-kildekode, for eksempel get_foo_bar().
However, boolean methods are easier to read if they avoid underscores and use an is prefix (not to be confused with methods that manipulate a boolean). Rationale: Identifies the return value as TRUE or FALSE and nothing else, e.g., isOpen, isHomed.
Do NOT use Not in a boolean name, it leads only leads to confusion when doing logical tests, e.g., isNotOnLimit or is_not_on_limit are BAD.
Variable names should avoid the use of upper case and underscores except for local or private names. The use of global variables should be avoided as much as possible. Rationale: Clarifies which are variables and which are methods. Public: e.g., axislimit Private: e.g., maxvelocity_ .
9.1. Spesifikke metodenavngivingskonvensjoner
Begrepet get og set bør brukes ved direkte tilgang til en attributt. Rasjonale: Indikerer formålet med funksjonen eller metoden, for eksempel get_foo, set_bar.
For methods involving boolean attributes, set & reset is preferred. Rationale: As above. e.g. set_amp_enable reset_amp_fault
Math intensive methods should use compute as a prefix. Rationale: Shows that it is computationally intensive and will hog the CPU. e.g. compute_PID
Abbreviations in names should be avoided where possible - The exception is for local variable names. Rationale: Clarity of code. e.g. pointer is preferred over ptr compute is preferred over cmp compare is again preferred over cmp.
Enumerates and other constants can be prefixed by a common type name, e.g., enum COLOR { COLOR_RED, COLOR_BLUE };
.
Excessive use of macros and defines should be avoided - Using simple methods or functions is preferred. Rationale: Improves the debugging process.
Include Statements Header files must be included at the top of a source file and not scattered throughout the body. They should be sorted and grouped by their hierarchical position within the system with the low level files included first. Include file paths should NEVER be absolute - Use the compiler -I flag instead to extend the search path. Rationale: Headers may not be in the same place on all systems.
Pointers and references should have their reference symbol next to the variable name rather than the type name. Rationale: Reduces confusion, e.g., float *x
or int &i
.
Implicit tests for zero should not be used except for boolean variables, e.g., if (spindle_speed != 0)
NOT if (spindle_speed)
.
Only loop control statements must be included in a for() construct, e.g., sum = 0; for (i=0; i<10; i++) { sum += value[i]; }
NOT: for (i=0, sum=0; i<10; i++) sum += value[i];
.
Likewise, executable statements in conditionals must be avoided, e.g., if (fd = open(file_name)
is bad.
Complex conditional statements should be avoided - Introduce temporary boolean variables instead.
Parentheses should be used in plenty in mathematical expressions - Do not rely on operator precedence when an extra parentheses would clarify things.
File names: C++ sources and headers use .cc and .hh extension. The use of .c and .h are reserved for plain C. Headers are for class, method, and structure declarations, not code (unless the functions are declared inline).
10. Python coding standards
Bruk PEP 8-stilen for Pythonkode.
11. Comp coding standards
In the declaration portion of a .comp file, begin each declaration at the first column. Insert extra blank lines when they help group related items.
Følg normal C-kodestil i kodedelen av en .comp-fil.