Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cpp_coding_standard.txt « docs - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: fa7bf65a7109e090cf9815656c3ae2a0865afd2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
We write code without warnings!

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 (but not all!) 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 in header files.
- We don't include system, std and boost headers directly, use #include "../std/<wrapper.hpp>"
- We ARE using C++ exceptions
- We are using all features of C++11 (the only known exception is thread_local which is not fully supported on all platforms)
- We don't use boost libraries which require linking (and prefer C++11 types over their boost counterparts)

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
- Don't specify std:: and boost:: prefixes (headers in std/ folder already have 'using std::string')
- Use right-to-left order for variables/params: string const & s (reference to the const string)
- In one line 'if', 'for', 'while' we do not use brackets. If one line 'for' or 'while' is combined with one line 'if' do use brackets for cycle.
- Space after the keyword in conditions and loops. Space after ';' in for loop
- Space between binary operators, but can skip according to operators priority: x = y*y + z*z;
- Space after double dash

// *********** Formatting Example/Guide/Reference ***********
#include "../std/math.hpp"

typedef double TMyTypeStartsWithCapitalTLetter;

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
{

template <class TTemplateTypeStartsWithCapitalTLetter>
void SomeFoo(int a, int b, TTemplateTypeStartsWithCapitalTLetter /* we avoid compilation warnings */)
{
  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);
      // Commented out call
      //Bar(c);
    }
  }
}

} // 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;
}


//if, for, while formatting

if (condition)
  foo();
else
  bar();

if (condition)
{
  if (condition)
    foo();
  else
    bar();
}

for (size_t i = 0; i < size; ++i)
  foo(i);


while (true)
{
  if (condition)
    break;
}

// Space after the keyword

if (condition)
{}

for (size_t i = 0; i < 5; ++i)
{}

while (condition)
{}

switch (i)
{}

// Space between operators, and don't use space between unary operator and expression
x = 0;
x = -5;
++x;
x--;
x *= 5;
if (x && !y)
{}
v = w * x + y / z;
v = w*x + y/z;
v = w * (x + z);

// space after double dash


Tips and Hints

- If you see outdated code which can be improved - DO IT NOW (but in the separate pull request)! Make this awesome world even more better! 
- Your code should work at least on [mac|win|linux|android][x86|x86_64], [ios|android][armv7|arm64] architectures
- Your code should compile well with gcc 4.8+ and clang 3.5+
- Try to avoid using any new 3party library if it is not fully tested and supported on all our platforms
- 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@maps.me mailing list to ask all developers and bugs@maps.me 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(DeveloperName): 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)
-- Use std::array::size() to calculate plain C-array's size
-- Declare your own exceptions with DECLARE_EXCEPTION(name, baseException), where baseException is usually RootException
-- Throw exceptions with MYTHROW(exceptionName, (message))
-- A lot of useful string conversion utils are in base/string_utils.hpp