Mercurial > hg > CbC > CbC_llvm
diff docs/CodingStandards.rst @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | 3a76565eade5 |
line wrap: on
line diff
--- a/docs/CodingStandards.rst Fri Nov 25 19:14:25 2016 +0900 +++ b/docs/CodingStandards.rst Fri Oct 27 17:07:41 2017 +0900 @@ -34,10 +34,10 @@ (e.g. the naming convention). This is because they are relatively new, and a lot of code was written before they were put in place. Our long term goal is for the entire codebase to follow the convention, but we explicitly *do not* -want patches that do large-scale reformating of existing code. On the other +want patches that do large-scale reformatting of existing code. On the other hand, it is reasonable to rename the methods of a class if you're about to -change it in some other way. Just do the reformating as a separate commit from -the functionality change. +change it in some other way. Just do the reformatting as a separate commit +from the functionality change. The ultimate goal of these guidelines is to increase the readability and maintainability of our common source base. If you have suggestions for topics to @@ -131,9 +131,8 @@ * Delegating constructors: N1986_ * Default member initializers (non-static data member initializers): N2756_ - * Only use these for scalar members that would otherwise be left - uninitialized. Non-scalar members generally have appropriate default - constructors. + * Feel free to use these wherever they make sense and where the `=` + syntax is allowed. Don't use braced initialization syntax. .. _N2118: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html .. _N2439: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm @@ -812,6 +811,21 @@ for (const auto *Ptr : Container) { observe(*Ptr); } for (auto *Ptr : Container) { Ptr->change(); } +Beware of non-determinism due to ordering of pointers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In general, there is no relative ordering among pointers. As a result, +when unordered containers like sets and maps are used with pointer keys +the iteration order is undefined. Hence, iterating such containers may +result in non-deterministic code generation. While the generated code +might not necessarily be "wrong code", this non-determinism might result +in unexpected runtime crashes or simply hard to reproduce bugs on the +customer side making it harder to debug and fix. + +As a rule of thumb, in case an ordered result is expected, remember to +sort an unordered container before iteration. Or use ordered containers +like vector/MapVector/SetVector if you want to iterate pointer keys. + Style Issues ============ @@ -942,8 +956,8 @@ .. code-block:: c++ - for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { - if (BinaryOperator *BO = dyn_cast<BinaryOperator>(II)) { + for (Instruction &I : BB) { + if (auto *BO = dyn_cast<BinaryOperator>(&I)) { Value *LHS = BO->getOperand(0); Value *RHS = BO->getOperand(1); if (LHS != RHS) { @@ -962,8 +976,8 @@ .. code-block:: c++ - for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { - BinaryOperator *BO = dyn_cast<BinaryOperator>(II); + for (Instruction &I : BB) { + auto *BO = dyn_cast<BinaryOperator>(&I); if (!BO) continue; Value *LHS = BO->getOperand(0); @@ -1233,6 +1247,12 @@ code for this branch. If the compiler does not support this, it will fall back to the "abort" implementation. +Neither assertions or ``llvm_unreachable`` will abort the program on a release +build. If the error condition can be triggered by user input then the +recoverable error mechanism described in :doc:`ProgrammersManual` should be +used instead. In cases where this is not practical, ``report_fatal_error`` may +be used. + Another issue is that values used only by assertions will produce an "unused value" warning when assertions are disabled. For example, this code will warn: @@ -1317,19 +1337,31 @@ individual enumerators. To suppress this warning, use ``llvm_unreachable`` after the switch. -Don't evaluate ``end()`` every time through a loop -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use range-based ``for`` loops wherever possible +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Because C++ doesn't have a standard "``foreach``" loop (though it can be -emulated with macros and may be coming in C++'0x) we end up writing a lot of -loops that manually iterate from begin to end on a variety of containers or -through other data structures. One common mistake is to write a loop in this -style: +The introduction of range-based ``for`` loops in C++11 means that explicit +manipulation of iterators is rarely necessary. We use range-based ``for`` +loops wherever possible for all newly added code. For example: .. code-block:: c++ BasicBlock *BB = ... - for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) + for (Instruction &I : *BB) + ... use I ... + +Don't evaluate ``end()`` every time through a loop +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In cases where range-based ``for`` loops can't be used and it is necessary +to write an explicit iterator-based loop, pay close attention to whether +``end()`` is re-evaluted on each loop iteration. One common mistake is to +write a loop in this style: + +.. code-block:: c++ + + BasicBlock *BB = ... + for (auto I = BB->begin(); I != BB->end(); ++I) ... use I ... The problem with this construct is that it evaluates "``BB->end()``" every time @@ -1340,7 +1372,7 @@ .. code-block:: c++ BasicBlock *BB = ... - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + for (auto I = BB->begin(), E = BB->end(); I != E; ++I) ... use I ... The observant may quickly point out that these two loops may have different