From 788a8e18b197dfc7f8a2f2a55383e0475f7768bb Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Mon, 11 Mar 2013 08:54:06 +0300 Subject: [PATCH] Added initial revision of C++ coding standard --- docs/cpp_coding_standard.txt | 122 +++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 docs/cpp_coding_standard.txt diff --git a/docs/cpp_coding_standard.txt b/docs/cpp_coding_standard.txt new file mode 100644 index 0000000000..fa8b237019 --- /dev/null +++ b/docs/cpp_coding_standard.txt @@ -0,0 +1,122 @@ +In general, Google's coding standard http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml is used and we strongly encourage to read it. + +Below are our specific exceptions to the Google's coding standard: + +- We use .cpp and .hpp files, not .cc and .h (.c and .h are used for C code), in UTF-8 encoding +- File names are lowercase with underscores, like file_reader.cpp +- We use #pragma once instead of the #define Guard +- We don't include system, std and boost headers directly, use #include "../std/" +- We ARE using C++ exceptions +- We don't support C++11 yet +- We don't use boost libraries which requires linking + + +Naming and formatting + +- We ALWAYS use two spaces indent and don't use tabs +- We don't have hardcoded line width, but keep it reasonable to fit on the screen +- Doxygen-style comments can be used +- Underscores are allowed only in prefixes for member variables and namespace names, like int m_countriesCount; namespace utf_parser + +// *********** Formatting Example *********** +#include "../std/math.hpp" + +class ComplexClass +{ +public: + Complex(double rePart, double imPart) + : m_re(rePart), m_im(imPart) + {} + + double Modulus() const + { + return sqrt(m_re * m_re + m_im * m_im); + } + +private: + // We use m_ prefix for member variables + double m_re; + double m_im; +}; + +namespace +{ + +void CamelCaseFunctionName(int lowerCamelCaseVar) +{ + static int counter = 0; + counter += lowerCamelCaseVar; +} + +} // namespace + +namespace lower_case +{ + +void SomeFoo(int a, int b) +{ + for (int i = 0; i < a; ++i) + { + // IMPORTANT! We DON'T use one-liners for if statements for easier debugging. + // The following syntax is invalid: if (i < b) Bar(i); + if (i < b) + Bar(i); + else + { + Bar(i); + Bar(b); + } + } +} + +} // namespace lower_case + +// Switch formatting +int Foo(int a) +{ + switch (a) + { + case 1: + Bar(1); + break; + + case 2: + { + Bar(2); + break; + } + + case 3: + default: + Bar(3); + break; + } + + return 0; +} + + + +Tips and Hints + +- Cover your code with unit tests! See examples for existing libraries +- Check Base and Coding libraries for most of the basic functions +- Ask your team if you have any questions +- Use dev@ mailing list to ask all developers and bugs@ mailing list to post bugs +- Release builds contain debugging information (for profiling), production builds are not +- If you don't have enough time to make it right, leave a // @TODO need to fix it comment +- Some useful macroses: +-- #ifdef DEBUG | RELEASE | OMIM_PRODUCTION +-- #ifdef OMIM_OS_ANDROID | OMIM_OS_IPHONE | OMIM_OS_MAC (and some other useful OS-related macroses, see std/target_os.hpp) +-- Use ASSERT(expression, (out message)) and ASSERT_XXXXXX macroses often to check code validity in DEBUG builds +-- Use CHECK(expression, (out message)) and CHECK_XXXXXX macroses to check code validity in all builds +-- Use LOG(level, (message)) for logging, below is more detailed description for level: + LINFO - always prints log message + LDEBUG - logs only in DEBUG + LWARNING - the same as LINFO but catches your attention + LERROR - the same as LWARNING, but crashes in DEBUG and works in RELEASE + LCRITICAL - the same as LERROR and ALWAYS crashes +-- Need scope guard? Check MY_SCOPE_GUARD(name, func) +-- Calculate array size with ARRAY_SIZE(arrayVariable) +-- Declare your own exceptions with DECLARE_EXCEPTION(name, baseException), where baseException is usually RootException +-- Throw exceptions with MYTHROW(exceptionName, (message))