CSR.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. CODING STYLE REQUIREMENTS
  2. Copyright (c) 2011-2017 Oleh Derevenko
  3. This article is provided to you under the terms of Artistic License 2.0
  4. (http://www.opensource.org/licenses/artistic-license-2.0).
  5. (I) General Coding Requirements
  6. =============================================================================
  7. 1. Not more than one complex construction per function
  8. ----------------------------------------------------------------------------
  9. A function must not contain more than one* operator from the following set:
  10. for, while, do..while, switch and constructions try..catch, try..finally.
  11. Moreover, those operators/constructions must not appear inside of a
  12. conditional operator.
  13. * Loop inclusion is allowed if multi-dimensional array must be iterated and
  14. all the elements are uniform and need to be processed linearly.
  15. try..finally construction inclusion is allowed for several resource
  16. allocations that need to be performed together.
  17. 2. Absence of jumps
  18. ----------------------------------------------------------------------------
  19. goto and continue operators must not be used.
  20. 3. Single exit point at the end of function
  21. ----------------------------------------------------------------------------
  22. A function must not have other exit points except for the end of its
  23. definition. If a function returns a value, return operator must be the last
  24. syntactical construction in the function.
  25. 4. Zero value means failure
  26. ----------------------------------------------------------------------------
  27. Function results must be chosen the way that binary zero value had a meaning
  28. of failure. Similarly, types must be designed so that binary zero element
  29. had the meaning of an invalid value (if invalid element concept is applicable
  30. for the type).
  31. 5. Variables and parameters are initialized with zeroes
  32. ----------------------------------------------------------------------------
  33. Variables and class fields must be initialized with values of binary zero
  34. presentation. Public enumerated types must be designed to have zero element
  35. and that element is to be the default element. Function default parameters
  36. must be chosen in the form to have binary zero value.
  37. 6. Variables are not reused
  38. ----------------------------------------------------------------------------
  39. Variables must not be reused for other purposes after they have already been
  40. used for something. The only value that might be stored in a variable is that
  41. described with its name.
  42. 7. Parameters passed by value are treated as constants
  43. ----------------------------------------------------------------------------
  44. Parameters that are passed by value must not be modified*. All of them must
  45. be treated as if they have been implicitly declared with const modifier.
  46. * An exception could be the case when a value loses its meaning (e.g. a
  47. pointer to an object being deleted).
  48. 8. Result assignment is performed at the end of function
  49. ----------------------------------------------------------------------------
  50. Every function returning a result must have a variable to contain the result
  51. of that function. It is to be declared (initialized if necessary) at the
  52. beginning of the function* and the only access to it after that should be its
  53. final value assignment. The assignment should be the last meaningful operator
  54. in an execution branch**. Several assignments, one per each execution branch,
  55. are allowed.
  56. * It is allowed to declare result variable with assignment immediately before
  57. return operator.
  58. ** It is allowed to include technical constructions like logging or
  59. performance measuring after result variable assignment.
  60. 9. Parameters by reference are not used in expressions
  61. ----------------------------------------------------------------------------
  62. Parameters of simple types passed by reference must be copied into local
  63. variables at function entry and then be assigned their final values at
  64. function exit.
  65. Output parameters can be initialized at function entry and must be assigned
  66. their final values immediately before the function result variable assignment.
  67. (II) Class Design Requirements
  68. =============================================================================
  69. 1. Classes work with their fields on their own
  70. ----------------------------------------------------------------------------
  71. A function or method must not call several methods of other class, some of
  72. them being used to return and the others being used to assign the class fields.
  73. Such a code must be implemented as a method of that other class.
  74. 2. No direct access to the fields
  75. ----------------------------------------------------------------------------
  76. All the work with class fields (including fields of own class) must be
  77. performed with aid of dedicated methods (accessors) that return and assign
  78. field values. Exceptions can be made for constructors/destructors and methods
  79. dedicated for field initialization/finalization.
  80. 3. Private fields only
  81. ----------------------------------------------------------------------------
  82. All class fields must be private.
  83. 4. No code in constructors and destructors
  84. ----------------------------------------------------------------------------
  85. Class constructors must not have raw code other than doing trivial field
  86. initialization. If creation of contained objects is necessary or other
  87. operations need to be done they are to be performed via calls to the class
  88. methods rather than placed directly in constructor. Initial zero-assignment
  89. to a field is always required even if that field is later to be
  90. unconditionally assigned in methods called from the constructor.
  91. Similarly, a destructor must free contained objects with calls to the class
  92. methods rather than containing that code inline.
  93. 5. No code in callbacks
  94. ----------------------------------------------------------------------------
  95. Event handlers, callback interface methods and static callback methods must
  96. not have meaningful code within them. Their implementation should validate
  97. input arguments, convert them to proper internal types if necessary, and call
  98. one or more other methods of the class. These methods must not be declated in
  99. public section.
  100. 6. No public virtual methods
  101. ----------------------------------------------------------------------------
  102. Methods declared as virtual must not be public. The public calls to such
  103. methods must be wrapped with ordinary class methods.
  104. 7. No logical level violations
  105. ----------------------------------------------------------------------------
  106. Methods of lower logical levels must not call any methods of higher logical
  107. levels of the class. In particular, methods declared as protected and private
  108. must not call methods declared in public sections of own or ancestor classes.
  109. Methods declared as public may only call protected and private methods.
  110. Similarly classes of lower logical levels must not call public methods of
  111. classes at higher logical levels. Such calls are only possible via dedicated
  112. callback methods or callback interfaces.
  113. (III) Canonical Function Structures
  114. =============================================================================
  115. 0. Preamble
  116. ----------------------------------------------------------------------------
  117. Following are general function structures encouraged to be used for coding
  118. all the program logic. Any algorithm with branching can be implemented
  119. with these types of functions.
  120. Using these function structures helps to make code clear and error-proof.
  121. 1. A Boolean Function
  122. ----------------------------------------------------------------------------
  123. The Boolean Function can be used to implement algorithms with conditional
  124. branching.
  125. bool PerformSomeAction(...)
  126. {
  127. bool bResult = false;
  128. // Some linear code
  129. if (...)
  130. {
  131. // Some linear code
  132. if (...) // Optionally...
  133. {
  134. bResult = true;
  135. }
  136. }
  137. // Optionally...
  138. else if (...)
  139. {
  140. // Some linear code
  141. bResult = true;
  142. }
  143. return bResult;
  144. }
  145. The idea is to have result variable initialized with false at entry and then
  146. have an arbitrary structure of conditional operators with some branches
  147. changing result variable to true on exit.
  148. 2. A Validation Function
  149. ----------------------------------------------------------------------------
  150. The Validation Function is an alternative to Boolean Function to implement
  151. conditional logic. It's mostly convenient for implementing multi-step
  152. algorithms that may fail (like validations or initializations of multiple
  153. items of non-uniform nature).
  154. bool PerformSomeValidation(...)
  155. {
  156. bool bResult = false;
  157. do
  158. {
  159. // Some linear code
  160. // Optionally...
  161. if ( !(...) )
  162. {
  163. // Some error handling // Optionally...
  164. break;
  165. }
  166. // Optionally...
  167. if (...)
  168. {
  169. // Some linear code
  170. if ( !(...) )
  171. {
  172. // Some error handling // Optionally...
  173. break;
  174. }
  175. // Some linear code
  176. }
  177. bResult = true;
  178. }
  179. while (false);
  180. return bResult;
  181. }
  182. If function execution has side effects which need to be rolled back in case
  183. of failures on subsequent steps the function structure can be altered to the
  184. following form.
  185. bool PerformSomeInitialization(...)
  186. {
  187. bool bResult = false;
  188. bool bFirstSideEffectApplied = false, bSecondSideEffectApplied = false, ...;
  189. do
  190. {
  191. // Some linear code
  192. if ( !ExecuteFirstSideEffectApplication(...) )
  193. {
  194. // Some error handling // Optionally...
  195. break;
  196. }
  197. bFirstSideEffectApplied = true
  198. // Some linear code
  199. if ( !ExecuteSecondSideEffectApplication(...) )
  200. {
  201. // Some error handling // Optionally...
  202. break;
  203. }
  204. bSecondSideEffectApplied = true
  205. ...
  206. // Some linear code
  207. if ( !ExecuteLastSideEffectApplication(...) )
  208. {
  209. // Some error handling // Optionally...
  210. break;
  211. }
  212. bResult = true;
  213. }
  214. while (false);
  215. if (!bResult)
  216. {
  217. if (bFirstSideEffectApplied)
  218. {
  219. if (bSecondSideEffectApplied)
  220. {
  221. if (...)
  222. {
  223. ...
  224. }
  225. ExecuteSecondSideEffectRollback(...);
  226. }
  227. ExecuteFirstSideEffectRollback(...);
  228. }
  229. }
  230. return bResult;
  231. }
  232. 3. A Loop Validation Function
  233. ----------------------------------------------------------------------------
  234. The Loop Validation Function can be used for processing sequences of items
  235. while the processing of each or some individual items can fail.
  236. bool PerformLoopValidation(...)
  237. {
  238. bool bAnyFailure = false;
  239. for (...) // Or any other loop control operator
  240. {
  241. // Some linear code
  242. if ( !(...) )
  243. {
  244. // Some error handling // Optional
  245. bAnyFailure = true;
  246. break;
  247. }
  248. // Some linear code
  249. }
  250. bool bResult = !bAnyFailure;
  251. return bResult;
  252. }
  253. In case if a loop processing function may apply side effects on each step
  254. which need to be reverted in case of a failure on subsequent steps the
  255. functions need to be organized in the following four-function two-level
  256. structure.
  257. bool PerformLoopInitialization(...)
  258. {
  259. bool bResult = false;
  260. size_t nFailureItem;
  261. if (DoPerformLoopInitialization(..., nFailureItem))
  262. {
  263. bResult = true;
  264. }
  265. else
  266. {
  267. DoPerformLoopFinalization(..., nFailureItem);
  268. }
  269. return bResult;
  270. }
  271. void PerformLoopFinalization(...)
  272. {
  273. DoPerformLoopFinalization(..., npos); // Here "npos" stands for the invalid item index
  274. }
  275. bool DoPerformLoopInitialization(..., size_t &nOutFailureItem)
  276. {
  277. bool bAnyFailure = false;
  278. size_t nOutFailureItem = npos;
  279. for (...) // Or any other loop control operator
  280. {
  281. // Some linear code
  282. if ( !(...) )
  283. {
  284. // Some error handling // Optional
  285. nOutFailureItem = ...;
  286. bAnyFailure = true;
  287. break;
  288. }
  289. // Some linear code
  290. }
  291. bool bResult = !bAnyFailure;
  292. return bResult;
  293. }
  294. void DoPerformLoopFinalization(..., size_t nExternalFinalizationEndItem/*=npos*/)
  295. {
  296. size_t nFinalizationEndItem = nExternalFinalizationEndItem == npos
  297. ? ... /* total item count */
  298. : nExternalFinalizationEndItem;
  299. for (... /* loop until nFinalizationEndItem */) // Or any other loop control operator
  300. {
  301. // Some linear code
  302. RevertLoopItemSideEffects(...);
  303. }
  304. }