|
|
# KiCad C++ Source Code Style Guide #
Latest Publishing: February 2017
First Published: September 2010
written by
Wayne Stambaugh \<<stambaughw@gmail.com>\>andDick Hollenbeck \<<dick@softplc.com>\>
[TOC]
# 1. Introduction # {#csp_intro}
The purpose of this document is to provide a reference guide for KiCaddevelopers about how source code should be styled and formatted inKiCad. It is not a comprehensive programming guide because it does notdiscuss many things such as software engineering strategies, sourcedirectories, existing classes, or how to internationalize text. The goalis to make all of the KiCad source conform to this guide.
## 1.1 Why Coding Style Matters ## {#why}
You may be thinking to yourself that using the style defined in thisdocument will not make you a good programmer and you would be correct.Any given coding style is no substitute for experience. However, anyexperienced coder will tell that the only thing worse than looking atcode that is not in your preferred coding style, is looking at twentydifferent coding styles that are not your preferred coding style.Consistency makes a) problems easier to spot, and b) looking at code forlong periods of time more tolerable.
## 1.2 Enforcement ## {#enforcement}
The KiCad coding police are not going to break down your door and beatyou with your keyboard if you don't follow these guidelines (althoughthere are those who would argue that they should). However, there aresome very sound reasons why you should follow them. If you arecontributing patches, you are much more likely to be taken seriously bythe primary developers if your patches are formatted correctly. Busydevelopers don't have the time to go back and reformat your code. If youhave a desire to become a regular KiCad developer with commit access tothe development branch, you're not likely to get a glowingrecommendation by the lead developers if you will not follow theseguidelines. It is just good programming courtesy to follow this policybecause it is respectful of the investment already made by the existingdevelopers. The other KiCad developers will appreciate your effort.
**Warning**
**Do not modify this document without the consent of the projectleader. All changes to this document require approval.**
## 1.3 Tools ## {#tools}
There are some tools that can help you format your code easily.
[`clang-format`][clang-format] is a formatting tool that can both be used toprovide code-style automation to your editor of choice, as well as allow git tocheck formatting when committing (using a "Git hook"). You should install thisprogram to be able to use the Git hooks.
The style config file is `_clang-format`, and should be picked up automaticallyby `clang-format` when the `--style=file` option is set.
To enable the Git hooks (only needs to be done once per Git repo):
git config core.hooksPath .githooks
Set the `git clang-format` tool to use the provided `_clang-format` file:
git config clangFormat.style file
Then, to enable the format checker, set the `kicad.check-format` Git configto "true" for the KiCad repo:
git config kicad.check-format true
Without this config, the format checker will not run on commit, but you canstill check files staged for commit manually (see below).
If the hook is enabled, when you commit a change, you will be told if youhave caused any style violations (only in your changed code). You can then fixthe errors, either manually, or with the tools below.
If you are warned about formatting errors, but you are sure your style is correct,you can still commit:
git commit --no-verify
### Correcting Formatting Errors ## {#correcting-formatting-errors}
There is a Git aliases file that provides the right commands to show and correctformatting errors. Add to your repository config by running this command fromthe source directory:
git config --add include.path $(pwd)/helpers/git/format_alias
Then you can use the following aliases:
* `git check-format`: show any formatting warnings (but make no changes)* `git fix-format`: correct formatting (you will need to `git add` afterwards)
These aliases use a script, `tools/check-coding.sh`, which takes care of onlychecking the formatting for files that should be formatted. This script hasother uses:
* Make (or see only) violations in files modified in the previous commit (usefulwhen interactive-rebasing): * `check_coding.sh --amend [--diff]`
# 2. Naming Conventions # {#naming_conventions}
Before delving into anything as esoteric as indentation and formatting,naming conventions need to be addressed. This section does not attemptto define what names you use for your code. Rather, it defines the stylefor naming. See the references section for links to some excellentcoding references. When defining multiple word names use the followingconventions for improved readability:
- Use underscores for all upper and all lower case variables to make multiple word names more readable.- Use camel case for mixed case variable names.
Avoid mixing camel case and underscores.
**Examples**~~~~~~~~~~~~~{.cpp} CamelCaseName // if camelcase, then no underscores all_lower_case_name ALL_UPPER_CASE_NAME~~~~~~~~~~~~~
## 2.1 Class, Type Definitions, Name Space, and Macro Names ## {#definitions}
Class, typedef, enum, name space, and macro names should be comprised ofall capital letters.
**Examples**~~~~~~~~~~~~~{.cpp} class SIMPLE #define LONG_MACRO_WITH_UNDERSCORES typedef boost::ptr_vector<PIN> PIN_LIST; enum KICAD_T {...};~~~~~~~~~~~~~
## 2.2 Local, Private and Automatic Variables ## {#local_variables}
The first character of automatic, static local, and private variablenames should be lower case. This indicates that the variable will not be“visible” outside of the function, file, or class where they aredefined, respectively. The limited visibility is being acknowledged withthe lowercase starting letter, where lowercase is considered to be lessboisterous than uppercase.
**Examples**~~~~~~~~~~~~~{.cpp} int i; double aPrivateVariable; static char* static_variable = NULL;~~~~~~~~~~~~~
## 2.3 Public and Global Variables ## {#global_variables}
The first character of public and global variable names are to beuppercase. This indicates that the variable is visible outside the classor file in which it was defined. (An exception is the use of prefix `g_`which is also sometimes used to indicate a global variable.)
**Example**~~~~~~~~~~~~~{.cpp} char* GlobalVariable;~~~~~~~~~~~~~
## 2.4 Local, Private and Static Functions ## {#functions}
The first character of local, private, and static functions should belower case. This indicates that the function is not visible outside theclass or file where it is defined.
**Example**~~~~~~~~~~~~~{.cpp} bool isModified(); static int buildList( int* list );~~~~~~~~~~~~~
## 2.5 Function Arguments ## {#function_arguments}
Function arguments are prefixed with an 'a' to indicate these arearguments to a function. The 'a' stands for “argument”, and it alsoenables clever and concise Doxygen comments.
**Example**~~~~~~~~~~~~~{.cpp} /*/** */* * Copy aFoo into this instance. */ void SetFoo( int aFoo );~~~~~~~~~~~~~
Notice how the reader can say “a Foo” to himself when reading this.
## 2.6 Pointers ## {#pointers}
It is not desired to identify a pointer by building a 'p' into thevariable name. The pointer aspect of the variable pertains to type, notpurpose.
**Example**~~~~~~~~~~~~~{.cpp} MODULE* module;~~~~~~~~~~~~~
The purpose of the variable is that it represents a MODULE. Somethinglike `p_module` would only make that harder to discern.
## 2.7 Accessing Member Variables and Member Functions ## {#accessing_members}
We do not use “`this->`” to access either member variables or memberfunctions from within the containing class. We let C++ perform this forus.
# 3. Commenting # {#commenting}
Comments in KiCad typically fall into two categories: in line codecomments and Doxygen comments. In line comments have no set formattingrules other than they should have the same indent level as the code ifthey do not follow a statement. In line comments that follow statementsshould not exceed 99 columns unless absolutely necessary. The preventsword wrapping in an editor when the viewable columns is set to 100. Inline comments can use either the C++ or the C commenting style, but C++comments are preferred for single line comments or comments consistingof only a few lines.
## 3.1 Blank Lines Above Comments ## {#blank_lines_above_comments}
If a comment is the first thing on a line, then that comment should haveone or more blank lines above them. One blank line is preferred.
## 3.2 Doxygen ## {#doxygen}
Doxygen is a C++ source code documenting tool used by the project. Descriptive*.html files can be generated from the source code by installing Doxygen andbuilding the target named **doxygen-docs** and **dev-docs** that include thisdocument.
$ cd <kicad_build_base> $ make doxygen-docs
The generated source \*.html files will be placed into\<kicad\_project\_base\>/Documentation/doxygen/html/ and the developer's\*.html files will be placed into\<kicad\_project\_base\>/Documentation/development/doxygen/html/
Doxygen comments are used to build developer documentation from thesource code. They should normally be only placed in header files and notin \*.cpp files. This eliminates the obligation to keep two comments inagreement with each other. If the class, function, or enum, etc. isonly defined in a \*.cpp source file and not present in any header file,in which case the Doxygen comments should go into the \*.cpp source file.Again, avoid duplicating the Doxygen comments in both the header and\*.cpp source files.
KiCad uses the JAVADOC comment style defined in the [“Documenting thecode”][doccode] section of the Doxygen [manual][manual]. Don't forgetto use the special Doxygen tags: bug, todo, deprecated, etc., so otherdevelopers can quickly get useful information about your code. It isgood practice to actually generate the Doxygen \*.html files bybuilding target doxygen-docs, and then to review the quality of yourDoxygen comments with a web browser before submitting a patch.
[doccode]: http://www.doxygen.nl/manual/docblocks.html[manual]: http://www.doxygen.nl/manual
### 3.2.1 Function Comments ### {#function_comments}
These go into a header file, unless the function is a private (i.e.static) function known only to a \*.cpp file. The format of a functioncomment is chosen to serve a dual purpose role: delineation of thefunction declaration within the source code and to create a consistentleading sentence in the doxygen html output. The chosen format isto use a descriptive single line sentence, followed by a blank line,followed by an optional detailed description as the shown in the examplebelow.
**Example**~~~~~~~~~~~~~{.cpp} /*/** */* * Format and write text to an output stream. * * A really detailed description goes here if it's needed. * * @param aMestLevel is the multiple of spaces to precede the output with. * @param aFmt is a printf() style format string. * @param ... is a variable list of parameters that will get blended into * the output under control of the format string. * @return the number of characters output. * @throw IO_ERROR, if there is a problem outputting. */ int PRINTF_FUNC Print( int aNestLevel, const char* aFmt, ... );~~~~~~~~~~~~~
The single line description goes on the 2nd line of the comment. The\@return keyword if present, should describe the return value followedby a hyphen. The \@param keyword names a function parameter and the textfollowing should flow like a normal English sentence.
### 3.2.2 Class Comments ### {#class_comments}
A class comment describes a class declaration by giving the purpose anduse of the class. Its format is similar to a function comment. Doxygencan use the html \<p\> (paragraph designation) to begin a new paragraphin its output. So if the text of the comment is large, break it put intomultiple paragraphs.
**Example**~~~~~~~~~~~~~{.cpp} /*/** */* * An interface (abstract) class used to output UTF8 text in a * convenient way. * * The primary interface is "printf() like" but with support for * indentation control. The destination of the 8 bit wide text is * up to the implementer. * <p> * The implementer only has to implement the write() function, but * can also optionally re-implement GetQuoteChar(). * <p> * If you want to output a wxString, then use CONV_TO_UTF8() on it * before passing it as an argument to Print(). * <p> * Since this is an abstract interface, only classes derived from * this one may actually be used. */ class OUTPUTFORMATTER {~~~~~~~~~~~~~
# 4. Formatting # {#formatting}
This section defines the formatting style used in the KiCad source.
## 4.1 Indentation ## {#indentation}
The indentation level for the KiCad source code is defined as fourspaces. Please do not use tabs.
### 4.1.1 Defines ### {#defines}
There should be only one space after a \#define statement.
### 4.1.2 Column Alignment ### {#column_alignment}
Please try to align multiple consecutive similar lines into consistentcolumns when possible, such as \#define lines which can be thought of ascontaining 4 columns: \#define, symbol, value, and comment. Notice howall 4 columns are aligned in the example below.
**Example**~~~~~~~~~~~~~{.cpp} #define LN_RED 12 // my favorite #define LN_GREEN 13 // eco friendly~~~~~~~~~~~~~
Another common case is the declaration of automatic variables. These arepreferably shown in columns of type and variable name.
## 4.2 Blank Lines ## {#blank_lines}
### 4.2.1 Function Declarations ### {#function_declarations}
There should be 1 blank line above a function declaration in a classfile if that function declaration is presented with a Javadoc comment.This is consist with the statement above about blank lines abovecomments.
### 4.2.2 Function Definitions ### {#function_definitions}
Function definitions in *.cpp files will not typically be accompanied byany comment, since those are normally only in the header file. It isdesirable to set off the function definition within the *.cpp file byleaving two blank lines above the function definition.
### 4.2.3 If Statements ### {#if_statements}
There should be one blank line above if statements.
## 4.3 Line Length ### {#line_length}
The maximum line width is 99 columns. An exception to this is a longquoted string such as the internationalized text required to satisfyMSVC++, described below.
## 4.4 Strings ## {#strings}
The KiCad project team no longer supports compiling with MicrosoftVisual C++. When you need to break long strings into smaller substrings,please use the C99 compliant method for improved readability. Usingany of previously accepted methods defined below for breakinglong internationalized strings will no longer be accepted.
**Examples**~~~~~~~~~~~~~{.cpp} // This works with C99 compliant compilers is the **only** accepted method: wxChar* foo = _( “this is a long string broken ” “into pieces for readability.” );
// This works with MSVC, breaks POEdit, and is **not** acceptable: wxChar* foo = _( “this is a long string broken ” L“into pieces for readability” );
// This works with MSVC, is ugly, and is **not** accepted: wxChar* foo = _( “this is a long string \ broken into pieces for readability” );~~~~~~~~~~~~~
A second acceptable solution is to simply put the text all on oneline, even if it exceeds the 99 character line length limit. However,the preferred method is to break strings within the 99 character limitwhenever possible to prevent wrapping.
## 4.5 Trailing Whitespace ## {#trailing_whitespace}
Many programming editors conveniently indent your code for you. Some ofthem do it rather poorly and leave trailing whitespace. Thankfully, mosteditors come with a remove trailing whitespace macro or at least asetting to make trailing whitespace visible so you can see it andmanually remove it. Trailing whitespace is known to break some textparsing tools. It also leads to unnecessary diffs in the version controlsystem. Please remove trailing whitespace.
## 4.6 Multiple Statements per Line ## {#multiple_statements_per_line}
It is generally preferred that each statement be placed on its own line.This is especially true for statements without keywords.
**Example**~~~~~~~~~~~~~{.cpp} x=1; y=2; z=3; // Bad, should be on separate lines.~~~~~~~~~~~~~
## 4.7 Braces ## {#braces}
Braces should be placed on the line proceeding the keyword and indentedto the same level. It is not necessary to use braces if there is only asingle line statement after the keyword. In the case of if..elseif..else, indent all to the same level.
**Example**~~~~~~~~~~~~~{.cpp} void function() { if( foo ) { statement1; statement2; } else if( bar ) { statement3; statement4; } else statement5; }~~~~~~~~~~~~~
## 4.8 Parenthesis ## {#parenthesis}
Parenthesis should be placed immediately after function names andkeywords. Spaces should be placed after the opening parenthesis, beforethe closing parenthesis, and between the comma and the next argument infunctions. No space is needed if a function has no arguments.
**Example**~~~~~~~~~~~~~{.cpp} void Function( int aArg1, int aArg2 ) { while( busy ) { if( a || b || c ) doSomething(); else doSomethingElse(); } }~~~~~~~~~~~~~
## 4.9 Switch Formatting ## {#switch}
The case statement is to be indented to the same level as the switch.
**Example**~~~~~~~~~~~~~{.cpp} switch( foo ) { case 1: doOne(); break; case 2: doTwo(); // Fall through. default: doDefault(); }~~~~~~~~~~~~~
It is permitted to place all cases on a single line each, if that makes thecode more readable. This is often done for look-ups or translation functions. Inthis case, you will have to manually align for readability as appropriate andreject clang-format's suggested changes, if you use it:
~~~~~~~~~~~~~{.cpp} switch( m_orientation ) { case PIN_RIGHT: m_orientation = PIN_UP; break; case PIN_UP: m_orientation = PIN_LEFT; break; case PIN_LEFT: m_orientation = PIN_DOWN; break; case PIN_DOWN: m_orientation = PIN_RIGHT; break; }~~~~~~~~~~~~~
# 5. License Statement # {#license_statement}
There is a the file copyright.h which you can copy into the top ofyour new source files and edit the \<author\> field. KiCad depends onthe copyright enforcement capabilities of copyright law, and thismeans that source files must be copyrighted and not be released intothe public domain. Each source file has one or more owners.
# 6. Header Files # {#header_files}
Project \*.h source files should:
- contain a license statement- contain a nested include \#ifndef- be fully self standing and not depend on other headers that are not included within it.
The license statement was described above.
## 6.1 Nested Include #ifndef ## {#nested_include}
Each header file should include an \#ifndef which is commonly used toprevent compiler errors in the case where the header file is seenmultiple times in the code stream presented to the compiler. Justafter the license statement, at the top of the file there should belines similar to these (but with a file name specific token other than`RICHIO_H_`):
~~~~~~~~~~~~~{.cpp} #ifndef RICHIO_H_ #define RICHIO_H_~~~~~~~~~~~~~
And at the very bottom of the header file, use a line like this one:
~~~~~~~~~~~~~{.cpp} #endif // RICHIO_H_~~~~~~~~~~~~~
The \#ifndef wrapper begins after the license statement, and ends atthe very bottom of the file. It is important that it wrap any nested\#include statements, so that the compiler can skip them if the\#ifndef evaluates to false, which will reduce compilation time.
## 6.2 Headers Without Unsatisfied Dependencies ## {#header_depends}
Any header file should include other headers that it depends on. (Note:KiCad is not at this point now, but this section is a goal of theproject.)
It should be possible to run the compiler on any header file within theproject, and with proper include paths being passed to the compiler, theheader file should compile without error.
**Example**
$ cd /svn/kicad/testing.checkout/include $ g++ wx-config --cxxflags -I . xnode.h -o /tmp/junk
Such structuring of the header files removes the need within a client\*.cpp file to include some project header file before some other projectheader file. (A client \*.cpp file is one that intends to **use, notimplement,** the public API exposed within the header file.)
Client code should not have to piece together things that a header filewishes to expose. The exposing header file should be viewed as a fullysufficient **ticket to use** the public API of that header file.
This is not saying anything about how much to expose, only that thatwhich is exposed needs to be fully usable merely by including the headerfile that exposes it, with no additional includes.
For situations where there is a class header file and animplementation \*.cpp file, it is desirable to hide as much of theprivate implementation as is practical and any header file that is notneeded as part of the public API can and should be included only inthe implementation \*.cpp file. However, the number one concern ofthis section is that client (using) code can use the public API whichis exposed in the header file, merely by including that one headerfile.
# 7. I Wrote X Lines of Code Before I Read This Document # {#x_lines}
It's OK. We all make mistakes. Fortunately, KiCad provides aconfiguration file for the code beautifier uncrustify. Uncrustify won'tfix your naming problems but it does a pretty decent job of formattingyour source code. There are a few places where uncrustify makes someless than ideal indentation choices. It struggles with the stringdeclaration macros wxT(“”) and \_(“”) and functions used as arguments toother functions. After you uncrustify your source code, please review theindentation for any glaring errors and manually fix them. See theuncrustify [website][uncrustify] for more information.
[uncrustify]: http://uncrustify.sourceforge.net/
# 8. Show Me an Example # {#show_me_an_example}
Nothing drives the point home like an example. The source file richio.hbelow was taken directly from the KiCad source.
~~~~~~~~~~~~~{.cpp} /* * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
#ifndef RICHIO_H_ #define RICHIO_H_
// This file defines 3 classes useful for working with DSN text files and is named // "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
#include <string> #include <vector>
// I really did not want to be dependent on wxWidgets in richio // but the errorText needs to be wide char so wxString rules. #include <wx/wx.h> #include <cstdio> // FILE
/*/** */* * A class used to hold an error message and may be used to throw exceptions * containing meaningful error messages. */ struct IOError { wxString errorText;
IOError( const wxChar* aMsg ) : errorText( aMsg ) { }
IOError( const wxString& aMsg ) : errorText( aMsg ) { } };
/*/** */* * Read single lines of text into a buffer and increments a line number counter. */ class LINE_READER { protected:
FILE* fp; int lineNum; unsigned maxLineLength; unsigned length; char* line; unsigned capacity;
public:
/*/** */* * @param aFile is an open file in "ascii" mode, not binary mode. * @param aMaxLineLength is the number of bytes to use in the line buffer. */ LINE_READER( FILE* aFile, unsigned aMaxLineLength );
~LINE_READER() { delete[] line; }
/* int CharAt( int aNdx ) { if( (unsigned) aNdx < capacity ) return (char) (unsigned char) line[aNdx]; return -1; } */
/*/** */* * Read a line of text into the buffer and increments the line number * counter. * * @return is the number of bytes read, 0 at end of file. * @throw IO_ERROR when a line is too long. */ int ReadLine();
operator char* () { return line; }
int LineNumber() { return lineNum; }
unsigned Length() { return length; } };
/*/** */* * An interface (abstract class) used to output ASCII text in a convenient way. * * The primary interface is printf() like with support for indentation control. * The destination of the 8 bit wide text is up to the implementer. If you want * to output a wxString, then use CONV_TO_UTF8() on it before passing it as an * argument to Print(). * <p> * Since this is an abstract interface, only classes derived from this one * will be the implementations. * </p> */ class OUTPUTFORMATTER {
#if defined(__GNUG__) // The GNU C++ compiler defines this
// When used on a C++ function, we must account for the "this" pointer, // so increase the STRING-INDEX and FIRST-TO_CHECK by one. // See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html // Then to get format checking during the compile, compile with -Wall or -Wformat #define PRINTF_FUNC __attribute__ ((format (printf, 3, 4)))
#else #define PRINTF_FUNC // nothing #endif
public:
/*/** */* * Format and write text to the output stream. * * @param nestLevel is the multiple of spaces to preceed the output with. * @param fmt is a printf() style format string. * @param ... is a variable list of parameters that will get blended into * the output under control of the format string. * @return the number of characters output. * @throw IO_ERROR if there is a problem outputting, such as a full disk. */ virtual int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) = 0;
/*/** */* * Return the quoting character required for aWrapee. * * Return the quote character as a single character string for a given * input wrapee string. If the wrappee does not need to be quoted, * the return value is "" (the null string), such as when there are no * delimiters in the input wrapee string. If you want the quote character * to be assuredly not "", then pass in "(" as the wrappee. * <p> * Implementations are free to override the default behavior, which is to * call the static function of the same name. * </p> * * @param aWrapee is a string that might need wrapping on each end. * @return the quote character as a single character string, or "" * if the wrapee does not need to be wrapped. */ virtual const char* GetQuoteChar( const char* aWrapee ) = 0;
virtual ~OUTPUTFORMATTER() {}
/*/** */* * Get the quote character according to the Specctra DSN specification. * * @param aWrapee is a string that might need wrapping on each end. * @param aQuoteChar is a single character C string which provides the current * quote character, should it be needed by the wrapee. * * @return the quote_character as a single character string, or "" * if the wrapee does not need to be wrapped. */ static const char* GetQuoteChar( const char* aWrapee, const char* aQuoteChar ); };
/*/** */* * Implement an OUTPUTFORMATTER to a memory buffer. */ class STRINGFORMATTER : public OUTPUTFORMATTER { std::vector<char> buffer; std::string mystring;
int sprint( const char* fmt, ... ); int vprint( const char* fmt, va_list ap );
public:
/*/** */* * Reserve space in the buffer */ STRINGFORMATTER( int aReserve = 300 ) : buffer( aReserve, '\0' ) { }
/*/** */* * Clears the buffer and empties the internal string. */ void Clear() { mystring.clear(); }
/*/** */* * Remove whitespace, '(', and ')' from the internal string. */ void StripUseless();
std::string GetString() { return mystring; }
//-----<OUTPUTFORMATTER>------------------------------------------------ int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ); const char* GetQuoteChar( const char* wrapee ); //-----</OUTPUTFORMATTER>----------------------------------------------- };
#endif // RICHIO_H_~~~~~~~~~~~~~
# 9. Resources # {#resources}
There are plenty of excellent resources on the Internet on C++ codingstyles and coding do's and don'ts. Here are a few useful ones. In mostcases, the coding styles do not follow the KiCad coding style but thereis plenty of other good information here. Besides, most of them havesome great humor in them enjoyable to read. Who knows, you might evenlearn something new.
- [C++ Coding Standard][cppstandard]- [Linux Kernel Coding Style][kernel]- [C++ Operator Overloading Guidelines][overloading]- [Wikipedia's Programming Style Page][style]
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html[cppstandard]:http://www.possibility.com/Cpp/CppCodingStandard.html[kernel]:https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/process/coding-style.rst[overloading]:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html[style]:http://en.wikipedia.org/wiki/Programming_style
|