Make objects in range declarations immutable by default.
Rationale:
- Immutable objects are easier to reason about.
- Prevents accidental or hard-to-notice change of value.
Make objects in range declarations immutable by default.
Rationale:
@Empact I think it better to do (a subset of) the #12158 changes in follow-up PRs to keep this PR as mechanical and easy-to-review as possible. Basically what @laanwj suggested in #12158 (comment) :-)
This PR should hopefully be trivial to review :-)
Yeah, I like it as-is, just suggesting since the & additions wouldn't add much if anything to the line count, so it could be viewed as a form of compression.
Anyway, you have my Tested ACK 3299ed7.
make, make check and test/test_bitcoin ran green locally.
Rebased!
utACK 0143466
utACK 0143466
244 | @@ -245,7 +245,7 @@ int BlockAssembler::UpdatePackagesForAdded(const CTxMemPool::setEntries& already 245 | CTxMemPool::setEntries descendants; 246 | mempool.CalculateDescendants(it, descendants); 247 | // Insert all descendants (not yet in block) into the modified set 248 | - for (CTxMemPool::txiter desc : descendants) { 249 | + for (const CTxMemPool::txiter desc : descendants) {
const CTxMemPool::txiter&?
1602 | @@ -1603,7 +1603,7 @@ void CConnman::ThreadDNSAddressSeed() 1603 | 1604 | LOCK(cs_vNodes); 1605 | int nRelevant = 0; 1606 | - for (auto pnode : vNodes) { 1607 | + for (const auto pnode : vNodes) {
nit, s/auto/CNode*?
849 | @@ -850,7 +850,7 @@ void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pb 850 | // Erase orphan transactions included or precluded by this block 851 | if (vOrphanErase.size()) { 852 | int nErased = 0; 853 | - for (uint256 &orphanHash : vOrphanErase) { 854 | + for (const uint256 &orphanHash : vOrphanErase) {
const uint256&?
2271 | @@ -2272,7 +2272,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr 2272 | } 2273 | } 2274 | 2275 | - for (uint256 hash : vEraseQueue) 2276 | + for (const uint256 hash : vEraseQueue)
Same as above.
I've only made some comments where I think the iterated type can be const &. Can you review the whole change if you agree with such change?
@promag Thanks for reviewing! Feedback addressed. Please re-review :-)
37 | @@ -38,7 +38,7 @@ RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool) 38 | CTxMemPoolEntry entry = *pool.mapTx.find(tx.GetHash()); 39 | pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); 40 | 41 | - for (CTxMemPool::txiter it : setAncestors) { 42 | + for (const CTxMemPool::txiter it : setAncestors) {
nit: Could be a reference too for consistency with src/miner.cpp.
441 | @@ -442,7 +442,7 @@ void BitcoinApplication::requestShutdown() 442 | 443 | #ifdef ENABLE_WALLET 444 | window->removeAllWallets(); 445 | - for (WalletModel *walletModel : m_wallet_models) { 446 | + for (const WalletModel *walletModel : m_wallet_models) {
nit: Whitespace
I'm not sure I understand what whitespace change you're suggesting? :-)
Just that the developer-notes prefer WalletModel*. Fine to ignore.
531 | @@ -532,14 +532,14 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request) 532 | 533 | if (!fVerbose) { 534 | UniValue o(UniValue::VARR); 535 | - for (CTxMemPool::txiter ancestorIt : setAncestors) { 536 | + for (const CTxMemPool::txiter ancestorIt : setAncestors) {
nit: Same for this file
87 | @@ -88,7 +88,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendan 88 | int64_t modifySize = 0; 89 | CAmount modifyFee = 0; 90 | int64_t modifyCount = 0; 91 | - for (txiter cit : setAllDescendants) { 92 | + for (const txiter cit : setAllDescendants) {
nit: Same
3209 | @@ -3210,7 +3210,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256 3210 | { 3211 | AssertLockHeld(cs_wallet); // mapWallet 3212 | DBErrors nZapSelectTxRet = WalletBatch(*database,"cr+").ZapSelectTx(vHashIn, vHashOut); 3213 | - for (uint256 hash : vHashOut) 3214 | + for (const uint256 hash : vHashOut)
nit: Reference?
609 | @@ -610,7 +610,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet) 610 | if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta) 611 | pwallet->UpdateTimeFirstKey(1); 612 | 613 | - for (uint256 hash : wss.vWalletUpgrade) 614 | + for (const uint256 hash : wss.vWalletUpgrade)
nit: References?
All nits, just calling out handling where inconsistent.
utACK 9a4655fd15e632d95651e4681936f8ea13457ae1
These changes should be obviously safe. Adding const to variable declarations should never introduce problems (as long as the result compiles). The same is true for converting const variables to references.
@Empact Updated version with nits addressed. @Empact @sipa @promag @ken2812221 Please re-review :-)
97 | @@ -98,7 +98,7 @@ class NodeImpl : public Node 98 | g_connman->GetNodeStats(stats_temp); 99 | 100 | stats.reserve(stats_temp.size()); 101 | - for (auto& node_stats_temp : stats_temp) { 102 | + for (const CNodeStats& node_stats_temp : stats_temp) {
This would be a performance regression.
Can you explain? If stats_temp is a std::vector<CNodeStats>, and you can loop over with CNodeStats&, shouldn't you also be able to take a const CNodeStats& without performance implication?
See below:
std::move(node_stats_temp)
This is a non-const reference so that the elements can be moved rather than copied.
Gotcha, thanks.
@sipa I disagree. std::move is still allowed on const references, they just... don't move. One such instance of this is here: #13249 (review)
It's unlikely to cause issues, only performance reductions, but code that relies on refcounts/lifetimes would potentially be affected. So I'm a bit more nervous about such a sweeping change.
@theuni Thanks for reviewing. Feedback addressed. Please re-review :-)
37 | @@ -38,7 +38,7 @@ RBFTransactionState IsRBFOptIn(const CTransaction &tx, CTxMemPool &pool) 38 | CTxMemPoolEntry entry = *pool.mapTx.find(tx.GetHash()); 39 | pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); 40 | 41 | - for (CTxMemPool::txiter it : setAncestors) { 42 | + for (const CTxMemPool::txiter& it : setAncestors) {
Not sure if it makes sense to take a const reference of a iterator...
@MarcoFalke Thanks for reviewing. Feedback addressed. Please re-review :-)
Again, I am not sure if it makes sense to take a const reference of a iterator...
After some reading I agree with @MarcoFalke, sorry for the suggestion.
@MarcoFalke @promag The remaining txiter const ref changes along the line of ...
- for (const CTxMemPool::txiter it : …) {
+ for (const CTxMemPool::txiter& it : …) {
... are required to make -Wrange-loop-analysis pass.
Drop const or keep &?
Drop const, since CTxMemPool::txiter is already a const iterator and the const does nothing useful, as far as I can see.
@MarcoFalke Feedback addressed. Please re-review :-)
@MarcoFalke I expect it to not matter at all, as in most cases the compiler will optimize things far enough to result in nearly identical code for reference or not.
I believe the clang warning code suggests references in case a copy can be avoided. I think we should follow those suggestions, as it has the best performance guarantees ignoring optimizations.
In practice, most iterators are just a single pointer, but some are not (std::vector<bool>'s iterators, for example).
@sipa I have no strong opinion on takeing a reference to an iterator, but I believe that using a const iterator instead of a const_iterator is just misleading and could lead to dangerous bugs.
Rebased! @MarcoFalke Just to clarify - are you OK with the changes after the latest round of updates? Any outstanding issues? :-)
Rebased!
Rebased!
Rebased! :-)
2389 | @@ -2390,7 +2390,7 @@ std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const 2390 | LOCK2(cs_main, cs_wallet); 2391 | AvailableCoins(availableCoins); 2392 | 2393 | - for (auto& coin : availableCoins) { 2394 | + for (const auto& coin : availableCoins) {
Could use const COutput& coin?
4492 | @@ -4493,7 +4493,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams) 4493 | 4494 | // Build forward-pointing map of the entire block tree. 4495 | std::multimap<CBlockIndex*,CBlockIndex*> forward; 4496 | - for (auto& entry : mapBlockIndex) { 4497 | + for (const auto& entry : mapBlockIndex) {
Most common usage when iterating mapBlockIndex is
for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
And there is also the above:
for (const BlockMap::value_type& entry : mapBlockIndex)
(I prefer the 1st).
1569 | @@ -1570,7 +1570,7 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wall 1570 | // Look up the inputs. We should have already checked that this transaction 1571 | // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our 1572 | // wallet, with a valid index into the vout array, and the ability to sign. 1573 | - for (auto& input : tx.vin) { 1574 | + for (const auto& input : tx.vin) {
Could use const CTxIn& input (most common usage).
Comments regarding auto usage.
@promag Thanks for reviewing. Feedback addressed. Please re-review :-)
Rebased! Please re-review :-)
utACK f34c8c4