refactor: Add [[nodiscard]] to functions returning bool+mutable ref#34520
refactor: Add [[nodiscard]] to functions returning bool+mutable ref#34520maflcko wants to merge 5 commits intobitcoin:masterfrom
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please copy-paste 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. |
facb886 to
fac5685
Compare
|
ACK fac5685 |
|
ACK fac5685 |
|
Concept ACK This looks like a good thing to add, but I wonder if handling these cases incrementally is the correct approach. Outside of these "getter" functions there are so many cases where adding [[nodiscard]] make sense too. There is Do you also want to add these couple of cases (also added one that takes a mutable pointer): diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index b2ce67c7c2..c2c2a94abd 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -154 +154 @@ public:
- template<typename K> bool GetKey(K& key) {
+ template<typename K> [[nodiscard]] bool GetKey(K& key) {
@@ -164 +164 @@ public:
- template<typename V> bool GetValue(V& value) {
+ template<typename V> [[nodiscard]] bool GetValue(V& value) {
diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h
index 127378ed2f..80a5dc2ac3 100644
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -99 +99 @@ private:
- bool getAddressData(const QString &address, std::string* name, wallet::AddressPurpose* purpose) const;
+ [[nodiscard]] bool getAddressData(const QString &address, std::string* name, wallet::AddressPurpose* purpose) const;
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 27fb76fc4a..a0f55b1cd1 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -199 +199 @@ std::unique_ptr<CCoinsViewCursor> CCoinsViewDB::Cursor() const
- i->pcursor->GetKey(entry);
+ (void)i->pcursor->GetKey(entry); |
fadf578 to
fa4db47
Compare
I wondered that, too. The patch here was written in 2018, but fell off the table. While I rebased it, some places where transformed to std::optional (which should be used in a few more places instead of nodiscard).
Are there? I think the attribute should only be used where it really makes sense.
I think this will do the exact opposite of what we want: It ignores functions that have a mutable ref param. It only adds it to functions that don't really need it in the first place. Happy to take a look at writing a clang-tidy plugin, maybe as a follow-up?
I've also seen this one, but left it for a follow-up, because it is not trivial to see if and why (void) would be the correct fix here. I wanted to keep this pull focussed on mostly mechanical changes for now.
Thx, done |
src/rpc/net.cpp
Outdated
| obj.pushKV("reachable", g_reachable_nets.Contains(network)); | ||
| obj.pushKV("proxy", proxy.IsValid() ? proxy.ToString() : std::string()); | ||
| obj.pushKV("proxy", is_valid ? proxy.ToString() : std::string{}); | ||
| obj.pushKV("proxy_randomize_credentials", proxy.m_tor_stream_isolation); |
There was a problem hiding this comment.
Shouldn't proxy.m_tor_stream_isolation also be conditional on is_valid ?
There was a problem hiding this comment.
Yeah, but I guess std::optional could make more sense. Done in #34741 and moved this into draft for now.
src/script/interpreter.cpp
Outdated
| while (pc < scriptSig.end()) { | ||
| opcodetype opcode; | ||
| scriptSig.GetOp(pc, opcode, data); | ||
| (void)scriptSig.GetOp(pc, opcode, data); |
There was a problem hiding this comment.
I'm uncomfortable with both declaring [[nodiscard] bool GetOp(...) and then discarding the return value in consensus code (or non-test code in general).
The earlier scriptSig.IsPushOnly() should guarantee that GetOp will never return false, so perhaps Assume(scriptSig.GetOp(pc, opcode, data)) would be better here?
| // If we have the cache, just get the parent xpub | ||
| if (cache != nullptr) { | ||
| cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub); | ||
| (void)cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub); |
There was a problem hiding this comment.
Perhaps:
if (cache == nullptr || !cache->GetCachedLastHardenedExtPubKey(m_expr_index,xpub) || !xpub.pubkey.IsValid()) {
// cache miss, or not cache, or need privkey
...
}
assert(xpub.pubkey.IsValid());There was a problem hiding this comment.
Haven't looked here. This is still in draft and I may take a look on the next rebase.
Also, use the return value in the test. Otherwise, compilation warns:
src/test/transaction_tests.cpp:906:9: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
906 | t.vin[0].scriptSig.GetOp(pc, opcode); // advance to next op
| ^~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
1 warning generated.
Also, mark the return value as unused in one place, which is checked in
the line after. This avoids a compile warning:
src/script/descriptor.cpp:552:13: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
552 | cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
1 warning generated.
Also, refactor the rpc code to check the return value (which is
identical to proxy.IsValid()). Otherwise, the compiler would warn:
src/rpc/net.cpp:622:9: warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
622 | GetProxy(network, proxy);
| ^~~~~~~~ ~~~~~~~~~~~~~~
1 warning generated.
Legacy code often used a function signature of the form
bool Get...(const& in, mut& in_out);to implement a getter that optionally returns a value.In modern code, this can be replaced by
std::optional<_> Get...(const& in);.However, some legacy code remains. To ensure that the "imaginary optional" is not unwrapped when the getter returns false, add a C++17
[[nodiscard]]attribute to all those legacy functions.There were only a few places that ignored the return value. I've fixed them in separate commits.
This should be easy to review via
--word-diff-regex=.and then confirming that the attribute was added to such a getter.