-
Notifications
You must be signed in to change notification settings - Fork 38k
refactor: actual immutable pointing #22787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
b7ac1de
to
30d9674
Compare
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Hopefully now that this has bitten you once, you'll not get tripped up by it again. FWIW, I think the notation for smart pointers:
is a bit easier to read than for raw pointers:
This is also similar for STL containers:
|
I can easily move the That's not what my PR is about though: it's about putting
It is definitely not the first time it's bitten me, personally, but maybe I'm just slow. :) Edit: it bites me often because I keep thinking of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not what my PR is about though: it's about putting const inside the shared pointer, which is a feature that is supported, and that makes the thing inside it immutable, which is what you expect when you see the const sign.
Ah, sorry - I misunderstood. I have no objection to making const things const, although I have a strong preference for following the convention of placing const
on the left side of the type.
src/wallet/interfaces.cpp
Outdated
std::unique_ptr<Wallet> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings) override | ||
{ | ||
std::shared_ptr<CWallet> wallet; | ||
std::shared_ptr<CWallet> const wallet; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declaring a local const std::shared_ptr<T> const_ptr;
is pointless. It can't be set to anything after this declaration since it's const.
In fact, this wallet
variable isn't used, so I think it can just be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this one just sorta tagged along. I have no idea why it is there, so I didn't touch it beyond letting it tag along with the convention change.
I'm totally fine with putting |
636ffa9
to
247e7a3
Compare
Switched to left-hand- |
247e7a3
to
cf89cbe
Compare
Concept ACK |
Concept ACK Const-correctness is important; to quote Herb Sutter on this subject:
(source: "Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions") |
Concept ACK |
Concept ACK (For historians, the discussion started here: https://github.com/bitcoin/bitcoin/pull/22751/files#r693517224) Edit: Maybe some of these can be converted too:
|
@kiminuo I'm limiting the scope on this PR to only shared pointers to |
cf89cbe
to
6b98ce3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK.
6b98ce3 could just change to std::shared_ptr<const T>
though.
I'm not sure I follow. Are you suggesting replacing |
While const shared_ptr<X> gives us an immutable shared pointer to a mutable X (we can't set it to some other X later), shared_ptr<const X> gives us a shared pointer to an immutable X. Importantly, we can recast shared_ptr<X> into shared_ptr<const X>, but not the other way around. We do this for two reasons: because it makes the code safer to guarantee the wallet is not modified, and because it further dispells the misconception that const shared_ptr<X> gives immutability to X.
@promag That makes sense to me, but it isn't clear to the reviewer why some lines are left as |
Concept ACK |
So should the lines like the following ones be fixed too? I mean to move
Produced by: Get-ChildItem -Recurse *.* | Select-String "std::shared_ptr<CWallet>" | Select-String "const std::shared_ptr<CWallet>" -notMatch |
It's tempting. Right now I'm only changing the lines that I'm touching for other reasons. If others agree, I can ramp it up to include all cases. |
6b98ce3
to
52a26e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-ACK 52a26e0
Verified via git range-diff 6b98ce32...52a26e08
that changes since my previous ACK were only rebase-related.
Introduce convention to use const shared pointers everywhere, unless the shared pointer is modified at some point, which it very rarely is. We want this convention, as it helps alleviate the misconception that a const shared pointer somehow results in a pointer to an immutable object, which is false.
While const shared_ptr<X> gives us an immutable shared pointer to a mutable X (we can't set it to some other X later), shared_ptr<const X> gives us a shared pointer to an immutable X. Importantly, we can recast shared_ptr<X> into shared_ptr<const X>, but not the other way around. We do this for two reasons: because it makes the code safer to guarantee the wallet is not modified, and because it further dispells the misconception that const shared_ptr<X> gives immutability to X.
52a26e0
to
54011e7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-ACK 54011e7
Verified via git range-diff 52a26e08...54011e7a
that changes since my previous ACK were only rebase-related.
54011e7 refactor: use CWallet const shared pointers when possible (Karl-Johan Alm) 9646198 refactor: const shared_ptrs (Karl-Johan Alm) Pull request description: ```C++ const std::shared_ptr<CWallet> wallet = x; ``` means we can not do `wallet = y`, but we can totally do `wallet->DestructiveOperation()`, contrary to what that line looks like. This PR * introduces a new convention: always use const shared pointers to `CWallet`s (even when we mutate the pointed-to thing) * uses `const shared_ptr<const CWallet>` everywhere where wallets are not modified In the future, this should preferably apply to all shared pointers, not limited to just `CWallet`s. Both of these serve the same purpose: to dispell the misconception that `const shared_ptr<X>` immutates `X`. It doesn't, and it's dangerous to leave this misconception as is, for obvious reasons. ACKs for top commit: theStack: re-ACK 54011e7 Tree-SHA512: 3bf4062fc821751be30770c6b4ead10a016847970f155a0a5156f304347d221b9830840030c2fbfba8cd1e282f4eda45f5b4107fe6df8138afdcb6c2e95a2836
…vkey,wallet} d150fe3 refactor: use `CWallet` const shared pointers in dump{privkey,wallet} RPCs (Sebastian Falbesoner) ec2792d refactor: use const `LegacyScriptPubKeyMan` references in dump{privkey,wallet} RPCs (Sebastian Falbesoner) 29905c0 refactor: avoid multiple key->metadata lookups in dumpwallet RPC (Sebastian Falbesoner) Pull request description: ~~This PR is based on #22787 ("refactor: actual immutable pointing"), which should be reviewed first.~~ (merged by now) It aims to make the CWallet shared pointers actually immutable also for the `dumpprivkey` and `dumpwallet` RPC methods. For doing that, some more preparations are needed; we need a const-counterpart to the helper `EnsureLegacyScriptPubKeyMan` that accepts a const CWallet pointer and accordingly also returns a const `LegacyScriptPubKeyMan` instance. The metadata lookup in `dumpwallet` is changed to not need a mutable `ScriptPubKeyMan` instance by avoiding using the `operator[]` in its mapKeyMetadata map, which also avoids repeated lookups. ACKs for top commit: laanwj: Code review ACK d150fe3 Tree-SHA512: 90ac05e21f40c6d0ebb479a71c545da2fd89940b9ca3409d9f932abc983bf8830d34c45086e68880d0d1e994846fbefee7534eec142ff4268e0fa28a1a411d36
…ump{privkey,wallet} d150fe3 refactor: use `CWallet` const shared pointers in dump{privkey,wallet} RPCs (Sebastian Falbesoner) ec2792d refactor: use const `LegacyScriptPubKeyMan` references in dump{privkey,wallet} RPCs (Sebastian Falbesoner) 29905c0 refactor: avoid multiple key->metadata lookups in dumpwallet RPC (Sebastian Falbesoner) Pull request description: ~~This PR is based on bitcoin#22787 ("refactor: actual immutable pointing"), which should be reviewed first.~~ (merged by now) It aims to make the CWallet shared pointers actually immutable also for the `dumpprivkey` and `dumpwallet` RPC methods. For doing that, some more preparations are needed; we need a const-counterpart to the helper `EnsureLegacyScriptPubKeyMan` that accepts a const CWallet pointer and accordingly also returns a const `LegacyScriptPubKeyMan` instance. The metadata lookup in `dumpwallet` is changed to not need a mutable `ScriptPubKeyMan` instance by avoiding using the `operator[]` in its mapKeyMetadata map, which also avoids repeated lookups. ACKs for top commit: laanwj: Code review ACK d150fe3 Tree-SHA512: 90ac05e21f40c6d0ebb479a71c545da2fd89940b9ca3409d9f932abc983bf8830d34c45086e68880d0d1e994846fbefee7534eec142ff4268e0fa28a1a411d36
const std::shared_ptr<CWallet> wallet = x;
means we can not do
wallet = y
, but we can totally dowallet->DestructiveOperation()
, contrary to what that line looks like.This PR
CWallet
s (even when we mutate the pointed-to thing)const shared_ptr<const CWallet>
everywhere where wallets are not modifiedIn the future, this should preferably apply to all shared pointers, not limited to just
CWallet
s.Both of these serve the same purpose: to dispell the misconception that
const shared_ptr<X>
immutatesX
. It doesn't, and it's dangerous to leave this misconception as is, for obvious reasons.