Merge-request: KT-MR-7880 Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
Code style for C++
TODO: Expand beyond naming and formatting
Headers
- Headers should live in the same folder with it's implementation counterpart (if there's one) TODO: This does not work with multiple implementations of a single header.
- Headers can use either
#pragma onceor header guards. - Headers that are designed to be included into both
.cpp/.mmand.c/.mshould have extension.h - Headers that are designed to be included into
.cpp/.mmonly should have extension.hpp
Namespace usage
- Do not use namespace blocks inside implementation files (
*.c,*.cpp,*.m,*.mm). Use fully qualified names for definitions. - Do not use
extern "C"blocks inside implementation files.
Runtime-specific
- Put main module inside
namespace kotlin - Put other modules under
namespace kotlinin a nestednamespace [module_name] - Put implementation details inside
.h/.hppinto a nestednamespace internal(e.g. implementation details of modulemmgo intonamespace kotlin { namespace mm { namespace internal { ... } } }) - Put implementation details inside
.cpp/.mminto a global anonymousnamespace - For
extern "C"declarations emulate namespaces withKotlin_[module_name]_prefixes. - To mark type as move-only, privately inherit from
kotlin::MoveOnly - To mark type unmovable and uncopyable, privately inherit from
kotlin::Pinned - Use
std_support::*containers and smart pointers instead ofstd::*ones. The former ones default to runtime-specific allocator. - Use
new (std_support::kalloc) T(...)(defined instd_support/New.hppinstead ofnew T(...)andstd_support::kdelete(ptr)instead ofdelete ptr. The former ones use runtime-specific allocator.
Naming
- Types should use
PascalCase - Local variables and function parameters should use
camelCase - Global variables should use
camelCase - Constants should use
kPascalCase(with prefixk) - Private functions (not visible outside a compilation unit) should use
camelCase - Exported functions (declared in headers or shared with Kotlin) should use
PascalCase - Member fields should use
camelCase. Private member fields should add_suffix:camelCase_ - Member functions should use
camelCase - Macros should use
SCREAMING_SNAKE_CASE - namespaces should use
snake_case enumandenum classmembers should usekPascalCase
If API is designed to mimic C++ stdlib (e.g. stubbing <atomic> for platforms that do not support it), its allowed
to follow stdlib naming conventions.
Formatting
For automated formatting you can use config for CLion or clang-format (see config at the repo's root). Note, that CLion uses clang-format by default; this can be turned off if you prefer to use rules from CLionFormat.xml.
Since 1.8.20 there's also a :kotlin-native:clangFormat task that will effectively run git-clang-format -f $(git merge-base origin/master HEAD) -- kotlin-native/.
The task accepts optional arguments --parent to specify base branch other than origin/master, and --interactive to run the tool with -p flag and interactively accept or reject formatted patches.
Formatting rules are designed to closely mirror Kotlin rules.
- Use spaces instead of tabs. Indentation width is 4 spaces. Continuation width is 8 spaces
- Do not indent namespaces
- Visibility modifiers are placed without indentation
- All operators should be wrapped with a space or a line break
- In pointer and reference definitions
*and&should be placed on a type instead of a variable - In pointer to functions prefer not to use
*at all. - Add a space between
templateand<