This document defines the coding standards and conventions for writing NVM Library code. To ensure readability and consistency within the code, the contributed code must adhere to the rules below.
The NVM Library coding style is quite similar to the style used for the SunOS product. A full description of that standard can be found here.
This document does not cover the entire set of recommendations and formatting rules used in writing NVML code, but rather focuses on some NVML-specific conventions, not described in the document mentioned above, as well as the ones the violation of which is most frequently observed during the code review. Also, keep in mind that more important than the particular style is consistency of coding style. So, when modifying the existing code, the changes should be coded in the same style as the file being modified.
Most of the common stylistic errors can be detected by the
style checker program
included in the repo.
Simply run make cstyle
or CSTYLE.ps1
to verify if your code is well-formatted.
Here is the list of the most important rules:
- The limit of line length is 80 characters.
- Indent the code with TABs, not spaces. Tab width is 8 characters.
- Put each variable declaration in a separate line.
- Do not use C++ comments (
//
). - Spaces around operators are mandatory.
- No whitespace is allowed at the end of line.
- For multi-line macros, do not put whitespace before
\
character. - Precede definition of each function with a brief, non-trivial description. (Usually a single line is enough.)
- Use
XXX
tag to indicate a hack, problematic code, or something to be done. - For pointer variables, place the
*
close to the variable name not pointer type. - Avoid unnecessary variable initialization.
- Never type
unsigned int
- just useunsigned
in such case. Same withlong int
andlong
, etc. - Sized types like
uint32_t
,int64_t
should be used when there is an on-media format. Otherwise, just useunsiged
,long
, etc. - Functions with local scope must be declared as
static
.
- Make sure you have the right to submit your contribution under the BSD license, especially if it is based upon previous work. See CONTRIBUTING.md for details.
- A copy of the BSD-style License must be placed at the beginning of each source file, script or man page (Obviously, it does not apply to README's, Visual Studio projects and *.match files.)
- When adding a new file to the repo, or when making a contribution to an existing file, feel free to put your copyright string on top of it.
- Keep identifier names short, but meaningful. One-letter variables are discouraged.
- Use proper prefix for function name, depending on the module it belongs to.
- Use under_score pattern for function/variable names. Please, do not use neither CamelCase nor Hungarian notation.
- UPPERCASE constant/macro/enum names.
- Capitalize first letter for variables with global or module-level scope.
- Avoid using
l
as a variable name, because it is hard to distinguishl
from1
on some displays.
- Do not ever add
#ifdef <OS>
sections lightly. They should be treated as technical debt and avoided when possible. - Use
_WIN32
macro for conditional directives when including code using Windows-specific API. - Use
_MSC_VER
macro for conditional directives when including code using VC++ or gcc specific extensions. - In case of large portions of code (i.e. a whole function) that have different implementation for each OS, consider moving them to separate files. (i.e. xxx_linux.c and xxx_windows.c)
- Keep in mind that
long int
is still 32-bit on 64-bit Windows. Remember to uselong long
types whenever it applies, as well as proper formatting strings and type suffixes (i..%llu
,ULL
). - Standard compliant solutions should be used in preference of compiler-specific ones. (i.e. static inline functions versus statement expressions)
- Do not use formatting strings that are not supported by Windows implementations
of printf()/scanf() family. (like
%j
or%m
) - It is recommended to use
PRI*
andSCN*
macros in printf()/scanf() functions for width-based integral types (uint32_t
,int64_t
, etc.).
- Put
LOG(3, ...)
at the beginning of each function. Consider using higher log level for most frequently called routines. - Make use of
COMPILE_ERROR_ON
andASSERT*
macros. - Use
ERR()
macro to log error messages.