Last active
April 25, 2019 11:54
-
-
Save sasq64/0cf7ba4cc656d2fb1ff38d4022365fd8 to your computer and use it in GitHub Desktop.
Revisions
-
sasq64 revised this gist
Apr 25, 2019 . 1 changed file with 3 additions and 28 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,7 +9,7 @@ preferences. They represent -- for the most part -- an emerging C++14 "modern" style * Don't use naked new/delete * Prefer passing and returning by value * Use unique_ptr unless you need sharing * Return `unique_ptr` from factory functions, they can be turned into `shared_ptr`. * Don't use indexed for loop when foreach is enough. @@ -102,33 +102,8 @@ of the class changes. As a special case, function arguments should of course have good names, but _you should not need to see them to understand the function_. The usage of a function should perferably be clear by it's name and the _types_ of its arguments. ## Error Handling -
sasq64 revised this gist
Apr 11, 2019 . 1 changed file with 5 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -28,7 +28,6 @@ time to rename it or (better) move that logic somewhere else. ## Project layout We try to follow the _[pitchfork propsal](https://api.csswg.org/bikeshed/?force=1&url=https://raw.githubusercontent.com/vector-of-bool/pitchfork/develop/data/spec.bs)_ We use a single, top level `CMakeLists.txt` @@ -41,13 +40,13 @@ The cpp file should include the headers as its first line, even if it is otherwise empty. Use `#pragma once` instead of ifdef guards; it is supported by all compilers and is less error prone (and probably faster). Sort your includes; * The corresponding class h-file first. * Then other local include files. * Then 3rd party headers. * Last std library includes. Try to keep dependencies out of inlude files. -
sasq64 revised this gist
Apr 11, 2019 . 1 changed file with 19 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -17,7 +17,13 @@ C++14 "modern" style ## Class Design Try to avoid '-er' type classes (Manager, Controller, Handler etc). It's often hard to determine what their purpose is. Sometimes you need a class whos _only_ purpose is to handle a set of (logical) child classes. But they should normally be short and do only that. If actual business logic starts to sneak in to your manager class, it's either time to rename it or (better) move that logic somewhere else. ## Project layout @@ -172,11 +178,22 @@ We can then use _Doxygen_ to generate documentation. ### 80 Columns Boost uses 80 columns. The clang standard library uses 80 columns. Most lines are shorter, so a longer linewidth wastes more screen real estate. With `clang-format`, you don't need to do line breaking manually, it will format the code good enough to be readable. It is univerally understood that long lines are hard to read. This is why newspapers format things into columns. For code this can break up statements too much and at some point it will make it harder to read. As far as I know there has been no studies made to figure out where the "breaking point" lies, but I think the concencus in the community is that it is below 80 characters. Don't let the historical significance of the number fool you into thinking this is just a legacy rule. It's just a nice, even number that seems to be a good trade off between too long lines and two much wrapping. ### East const I prefer `fn(std::string const& arg)` instead of `fn(const std::string& arg)`. @@ -203,4 +220,3 @@ for everything. This guide still recommends the older more universal standard that is similar to Java and C#. I think this still reflects what most developers are used to, but it would be more correct to switch to snake case. We can still start types with upper case. -
sasq64 created this gist
Apr 11, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,206 @@ # C++ Developer Guide Please note; these rules are not random; nor are they my personal preferences. They represent -- for the most part -- an emerging 'de facto' standard for how modern C++ code is developed. ## Basics C++14 "modern" style * Don't use naked new/delete * Use a stack variables for short lived objects. * Use unique_ptr unless you need sharing * Return `unique_ptr` from factory functions, they can be turned into `shared_ptr`. * Don't use indexed for loop when foreach is enough. * Look to algorithms instead of complex foreach loops ## Class Design * Avoid '-er' type classes (Manager, Controller, Handler etc) ## Project layout We try to follow the _[pitchfork propsal](https://api.csswg.org/bikeshed/?force=1&url=https://raw.githubusercontent.com/vector-of-bool/pitchfork/develop/data/spec.bs)_ It tries to unify defacto standards. We use a single, top level `CMakeLists.txt` We also have a boot strapping `Makefile` so you can just type `make` after cloning. ## File structure Put the interface in the header and the implementation in the cpp file. The cpp file should include the headers as its first line, even if it is otherwise empty. Use `#pragma once` instead of ifdef guards; it is supported by all compilers and is less error prone (and faster). Sort your includes; The corresponding class h-file first. Then other local include files. Then 3rd party headers. Last std library includes. Try to keep dependencies out of inlude files. ## Source code style * LLVM as base * Spaces for tabs * 80 column limit ```cpp namespace ecp { class StateMachine { public: void doSomething(std::string const& name) { if (name.empty()) { return; } } }; } // namespace ecp ``` ## Naming Camel case, Upper case for classes and structs, lower case for methods and variables. Namespaces should be lower case and kept short. Use UPPERCASE only for macros, not for enums and contants, to avoid collisions with existing macros. If you need to name your member variables differently, use a _trailing_ underscore; ie `myMemberVariable_`. Priority; where to spend most time thinking about good names * Classes * Functions * Member variables * Function arguments * Local variables * For loop / small clause variables ie Think _really_ hard about what a class should be called so it conveys as clearly as possible what it does, and _change_ the name if the responsibility of the class changes. As a special case, function arguments should of course have good names, but _you should not need to see them to understand the function_. A function should be clear by it's name and the _types_ of its arguments. Ideally, never have two arguments with the same type to a function. Examples **Bad:** `copyFile(string to, string from)` **Better:** `copyFileToFrom(string t, string f)` **Better:** `copyFileToFrom(File target, File source)` **Bad:** `drawText(int x, int y, string text)` **Good:** `drawText(Vector2 pos, string text)` **Bad:** `webPost(string url, string data)` **Good:** `webPost(URL url, JSON data)` ## Error Handling > Distinguish between errors and nonerrors. A failure is an error if and only if > it violates a function's ability to meet its callees' preconditions, to > establish its own postconditions, or to reestablish an invariant it shares > responsibility for maintaining. Everything else is not an error. > >Herb Sutter Check pre conditions at compile time if possible (static_assert). For errors, we use exceptions. We can catch and rethrow in jni layer. ## Tools * `clang-format` everything -- don't spend mental energy on formatting source code. * `Address sanitizer` and `valgrind` to find memory problems and leaks. * `clang-tidy` for liniting. * `cmake-format` to keep the CMakeLists.txt clean. ## Testing Aim for test driven design. We use _catch2_ and put all our unit tests under `tests/` Since you don't have tests for your tests; Test code should be understandable and _correct by inspection_. Also because test code is a good starting place to understand the rest of the code. Avoid special test utility methods, or test base classes. Try to write top-down, understandable code. ## Documentation Try to document API level methods and classes with descriptive text, using<br/> `//! comments like these` We can then use _Doxygen_ to generate documentation. ## Motivation / Contention ### 80 Columns Boost uses 80 columns. The clang standard library uses 80 columns. Most lines are much shorter, so a longer linewidth wastes more screen real estate. With `clang-format`, you don't need to do line breaking manually, it will format the code good enough to be readable. ### East const I prefer `fn(std::string const& arg)` instead of `fn(const std::string& arg)`. There has been a lot of debate about this, but the concesus is basically that the first (east const) is more logical, but the second is the standard. Either one is OK. ### Curly braces Some C++ programmers (mainly those used to C#) prefer to put a new line before every curly brace. Java code never puts new lines before braces. The de facto C++ standard is a mix, and not really a better alternative than either Java or C#, but since there is no standard that is universal, we may as well go with the de facto C++ standard. ### Naming The C++ community is moving away from _CamelCase_ towards lower _snake_case_ for everything. This guide still recommends the older more universal standard that is similar to Java and C#. I think this still reflects what most developers are used to, but it would be more correct to switch to snake case. We can still start types with upper case.