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
refactor: Remove confusing P1008R1 violation in ATMPArgs #24404
The head ref may contain hidden characters: "2202-cpp\u{1F972}"
Conversation
I believe an alternative (and larger) fix would be to provide an explicit constructor that takes all members as arguments. Happy to switch to that, but for now I prefer the smaller patch. |
ACK facbbec
I prefer this as well, for other places where there's no uninitialized reference to take the bullet for us. |
CI error is the |
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. |
NACK. The point of a deleted constructor is to make the type stable to future modifications that might e.g. turn m_chainparams into p_chainparams. It's essentially an assertion. |
No, it is not. Even if no member was |
If you don't believe me, nor the paper P1008R1. You can try it yourself with a C++11 compiler of you choice. The following compiles fine with or without the struct ATMPArgs {
int a;
bool b;
ATMPArgs() = delete;
};
int main() { (void)ATMPArgs{}; } // compiles |
No that was not the point when writing this code. The intention was to prevent callers from specifying their own But as shown in the paper (and any compiler), deleting the default constructor doesn't prevent something like this. What does prevent this is that there's a reference in the struct so you can't create a default version of it. So deletion of the default constructor does nothing. This PR is essentially removing code that doesn't do anything and misleading/confusing documentation. |
This example looks scary: struct ATMPArgs {
int a = 42;
bool b;
ATMPArgs() = delete;
ATMPArgs(int) = delete;
};
int main()
{
constexpr ATMPArgs atm{0};
static_assert(atm.a == 0);
} |
I think it's also important to point out that P1008R1 was accepted into C++20 so keeping the delete would also remove the aggregate initialization that the static functions make use of to construct |
The workaround in P1008R1 is to add an explicit modifier to the deletions? Why is that not a workable option here? |
It wouldn't compile:
with diff on master: diff --git a/src/validation.cpp b/src/validation.cpp
index 035b5783c3..c714bfe575 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -530,7 +530,7 @@ public:
}
// No default ctor to avoid exposing details to clients and allowing the possibility of
// mixing up the order of the arguments. Use static functions above instead.
- ATMPArgs() = delete;
+ explicit ATMPArgs() = delete;
};
// Single transaction acceptance |
I've pushed the alternative fix I mentioned in comment 2 #24404 (comment) |
Suggested diff for testing: diff --git a/src/validation.cpp b/src/validation.cpp
index 3f64fcc067..900f85fc54 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -707,6 +707,14 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
if (tx.IsCoinBase())
return state.Invalid(TxValidationResult::TX_CONSENSUS, "coinbase");
+ ATMPArgs{ args.m_chainparams,
+ args.m_accept_time,
+ args.m_bypass_limits,
+ args.m_coins_to_uncache,
+ args.m_test_accept,
+ args.m_allow_bip125_replacement,
+ args.m_package_submission
+ };
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
std::string reason;
if (fRequireStandard && !IsStandardTx(tx, reason)) |
should you not also retain the explicit delete with a new explicit ctor? |
Happy to do so if there is any benefit? |
Tend toward leaving as-is. |
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.
code review ACK faa1aec
ACK faa1aec |
…ATMPArgs faa1aec Remove confusing P1008R1 violation in ATMPArgs (MarcoFalke) Pull request description: The `= delete` doesn't achieve the stated goal and it is also redundant, since it is not possible to default construct the `ATMPArgs` type. This can be tested with: ```diff diff --git a/src/validation.cpp b/src/validation.cpp index 2813b62462..1c939c0b8a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -519,6 +519,7 @@ public: /** Parameters for child-with-unconfirmed-parents package validation. */ static ATMPArgs PackageChildWithParents(const CChainParams& chainparams, int64_t accept_time, std::vector<COutPoint>& coins_to_uncache) { + ATMPArgs{}; return ATMPArgs{/* m_chainparams */ chainparams, /* m_accept_time */ accept_time, /* m_bypass_limits */ false, ``` Which fails on current master *and* this pull with the following error: ``` validation.cpp:525:22: error: reference member of type 'const CChainParams &' uninitialized ATMPArgs{}; ~^ validation.cpp:470:29: note: uninitialized reference member is here const CChainParams& m_chainparams; ^ 1 error generated. ``` Further reading (optional): * http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1008r1.pdf ACKs for top commit: achow101: ACK faa1aec glozow: code review ACK faa1aec Tree-SHA512: 16db2c9959a1996eafbfa533dc4d1483761b9d28295aed5a82b86abd7268da37c51c59ddc67c205165ecb415dbe637b12a0e1b3234d50ab0b3b79de66d7bd73e
The
= delete
doesn't achieve the stated goal and it is also redundant, since it is not possible to default construct theATMPArgs
type.This can be tested with:
Which fails on current master and this pull with the following error:
Further reading (optional):