From: Alex Bradbury Date: Thu, 31 Aug 2017 12:34:20 +0000 (+0000) Subject: [Docs] Update CodingStandards to recommend range-based for loops X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=43878499027fd679b32fd66877235806666f0aaa;p=llvm [Docs] Update CodingStandards to recommend range-based for loops The CodingStandards section on avoiding the re-evaluation of end() hasn't been updated since range-based for loops were adopted in the LLVM codebase. This patch adds a very brief section that documents how range-based for loops should be used wherever possible. It also moves example code in CodingStandards to use range-based for loops and auto when appropriate. Differential Revision: https://reviews.llvm.org/D37264 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312236 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst index 66e0c968f3f..c4e25e4216e 100644 --- a/docs/CodingStandards.rst +++ b/docs/CodingStandards.rst @@ -941,8 +941,8 @@ loops. A silly example is something like this: .. code-block:: c++ - for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { - if (BinaryOperator *BO = dyn_cast(II)) { + for (Instruction &I : BB) { + if (auto *BO = dyn_cast(&I)) { Value *LHS = BO->getOperand(0); Value *RHS = BO->getOperand(1); if (LHS != RHS) { @@ -961,8 +961,8 @@ It is strongly preferred to structure the loop like this: .. code-block:: c++ - for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { - BinaryOperator *BO = dyn_cast(II); + for (Instruction &I : BB) { + auto *BO = dyn_cast(&I); if (!BO) continue; Value *LHS = BO->getOperand(0); @@ -1322,19 +1322,31 @@ that the enum expression may take any representable value, not just those of individual enumerators. To suppress this warning, use ``llvm_unreachable`` after the switch. +Use range-based ``for`` loops wherever possible +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 (Instruction &I : *BB) + ... use I ... + Don't evaluate ``end()`` every time through a loop ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -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: +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 (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) + for (auto I = BB->begin(); I != BB->end(); ++I) ... use I ... The problem with this construct is that it evaluates "``BB->end()``" every time @@ -1345,7 +1357,7 @@ convenient way to do this is like so: .. 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