-
Notifications
You must be signed in to change notification settings - Fork 38.7k
scripted-diff: Use scoped enumerations (C++11, "enum class") #10742
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
6c9c5a7 to
4602120
Compare
src/rpc/protocol.h
Outdated
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.
Using strongly typed enums causes RPCErrorCode to be static_casted too often. To gain strongly typed enums we loose readability.
Especially when considering that a more correct way to cast a strongly typed enum is static_cast<std::underlying_type<RPCErrorCode>::type>(RPCErrorCode::RPC_MISC_ERROR)
Which is even more unreadable.
Instead I suggest forgetting strong typing for this enum but still solve the scoping problem with:
class RPCErrorCode
{
public:
enum
{
...
}
}
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.
Why not just make JSONRPCError accept a RPCErrorCode argument?
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.
@luke-jr Yes, that's my plan. I'll push those changes today hopefully :-)
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.
@luke-jr there would still be a few code == static_cast<int>(RPCErrorCode:: ...). But I agree it's not that many.
However changing JSONRPCError is kicking the can down to Pair where the conversion to int has to be done, or down to UniValue. It just seems to me like RPCErrorCode implicitly should be treated like an int since it will almost always be converted into one.
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.
@luke-jr @ArielLorenzo-Luaces Signature now changed:
-UniValue JSONRPCError(int code, const std::string& message)
+UniValue JSONRPCError(RPCErrorCode code, const std::string& message)Only three static_cast<int>(RPCErrorCode) remain, and since they are explicit they should not cause any surprises (as opposed to implicit conversions).
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.
I still think that RPCErrorCode and HTTPStatusCode are intrinsically different than the other enumerators, since they are sent over HTTP. They are also the only two that have explicit values assigned. They should be treated as integers always and they should require no conversion.
I would have suggested to hide conversion in encode/decode functions. Then the conversion would only have to be done once after receiving an http status. But then I see response.status >= 400 in bitcoin-cli.cpp. This suggests that HTTP status codes are not treated like enumerators and should not be compared to enumerators either.
RPCErrorCode and HTTPStatusCode should be treated more like macros instead.
Strong typing them would case unnecessary complexity due to the casting. But that would only be a problem if they begin to be used much more often, which is speculation on my part. So these changes are fine for now.
25333b1 to
1840ee7
Compare
e5a7dc6 to
5255dc7
Compare
|
Rebased! |
cd78823 to
28cd41d
Compare
|
Rebased again! :-) |
3091ec1 to
e4dd710
Compare
040b561 to
cd8b270
Compare
|
Rebased! :-) |
71ede09 to
1dcbb3c
Compare
|
@laanwj Would it be possible to get a 0.17.0 milestone for this PR? :-) |
|
Probably better to just merge this as there seems agreement to do it... |
…ass") 1f45e21 scripted-diff: Convert 11 enums into scoped enums (C++11) (practicalswift) Pull request description: Rationale (from Bjarne Stroustrup's ["C++11 FAQ"](http://www.stroustrup.com/C++11FAQ.html#enum)): > > The enum classes ("new enums", "strong enums") address three problems with traditional C++ enumerations: > > * conventional enums implicitly convert to int, causing errors when someone does not want an enumeration to act as an integer. > * conventional enums export their enumerators to the surrounding scope, causing name clashes. > * the underlying type of an enum cannot be specified, causing confusion, compatibility problems, and makes forward declaration impossible. > > The new enums are "enum class" because they combine aspects of traditional enumerations (names values) with aspects of classes (scoped members and absence of conversions). Tree-SHA512: 9656e1cf4c3cabd4378c7a38d0c2eaf79e4a54d204a3c5762330840e55ee7e141e188a3efb2b4daf0ef3110bbaff80d8b9253abf2a9b015cdc4d60b49ac2b914
…ons ("enum class")
0fee2b4 doc: Add note about our preference for scoped enumerations ("enum class") (practicalswift)
Pull request description:
Add note about our preference for scoped enumerations (`enum class`).
Context: #10742
Tree-SHA512: 0ab3465c2b734240cb38a05c2f6e75f1af54207a0f1a2e8115e7b367fd37e8966a2fc0240c6d4c2c66b6677b5f367eda4f4b783bbaa419777336c17f04adff06
…with some compilers) 43f3dec Remove enum specifier (to avoid re-declare scoped enum as unscoped) (donaloconnor) Pull request description: MSVC fails to compile with the changes made in #10742 The problem is enum types were changed to scoped (`enum class`) but in some places `enum` as an unscoped is used. This is a very simple fix and I've tested it. Edit: Had to remove enum altogether - `enum class` doesn't compile on clang. Tree-SHA512: 13e21666243585a133c74c81249a1fa4098d6b7aa3cda06be871fa017c0ad9bb7b0725f801160b9d31678448d668718197941fd84702ebdef15128c27d92cd70
References: - bitcoin/bitcoin#11423 - bitcoin/bitcoin#12600 - bitcoin/bitcoin#12082 Trivial References: - bitcoin/bitcoin#12393 - bitcoin/bitcoin#6539 - bitcoin/bitcoin#10742 - bitcoin/bitcoin@ecb11f5
References: - bitcoin/bitcoin#11423 - bitcoin/bitcoin#12600 - bitcoin/bitcoin#12082 Trivial References: - bitcoin/bitcoin#12393 - bitcoin/bitcoin#6539 - bitcoin/bitcoin#10742 - bitcoin/bitcoin@ecb11f5
References: - bitcoin/bitcoin#11423 - bitcoin/bitcoin#12600 - bitcoin/bitcoin#12082 Trivial References: - bitcoin/bitcoin#12393 - bitcoin/bitcoin#6539 - bitcoin/bitcoin#10742 - bitcoin/bitcoin@ecb11f5
…oin#10742) -BEGIN VERIFY SCRIPT- sed -i 's/enum DBErrors/enum class DBErrors/g' src/wallet/walletdb.h git grep -l DB_ | xargs sed -i 's/DB_\(LOAD_OK\|CORRUPT\|NONCRITICAL_ERROR\|TOO_NEW\|LOAD_FAIL\|NEED_REWRITE\)/DBErrors::\1/g' sed -i 's/^ DBErrors::/ /g' src/wallet/walletdb.h sed -i 's/enum VerifyResult/enum class VerifyResult/g' src/wallet/db.h sed -i 's/\(VERIFY_OK\|RECOVER_OK\|RECOVER_FAIL\)/VerifyResult::\1/g' src/wallet/db.cpp sed -i 's/enum ThresholdState/enum class ThresholdState/g' src/versionbits.h git grep -l THRESHOLD_ | xargs sed -i 's/THRESHOLD_\(DEFINED\|STARTED\|LOCKED_IN\|ACTIVE\|FAILED\)/ThresholdState::\1/g' sed -i 's/^ ThresholdState::/ /g' src/versionbits.h sed -i 's/enum SigVersion/enum class SigVersion/g' src/script/interpreter.h git grep -l SIGVERSION_ | xargs sed -i 's/SIGVERSION_\(BASE\|WITNESS_V0\)/SigVersion::\1/g' sed -i 's/^ SigVersion::/ /g' src/script/interpreter.h sed -i 's/enum RetFormat {/enum class RetFormat {/g' src/rest.cpp sed -i 's/RF_\(UNDEF\|BINARY\|HEX\|JSON\)/RetFormat::\1/g' src/rest.cpp sed -i 's/^ RetFormat::/ /g' src/rest.cpp sed -i 's/enum HelpMessageMode {/enum class HelpMessageMode {/g' src/init.h git grep -l HMM_ | xargs sed -i 's/HMM_BITCOIN/HelpMessageMode::BITCOIN/g' sed -i 's/^ HelpMessageMode::/ /g' src/init.h sed -i 's/enum FeeEstimateHorizon/enum class FeeEstimateHorizon/g' src/policy/fees.h sed -i 's/enum BlockSource {/enum class BlockSource {/g' src/qt/clientmodel.h git grep -l BLOCK_SOURCE_ | xargs sed -i 's/BLOCK_SOURCE_\(NONE\|REINDEX\|DISK\|NETWORK\)/BlockSource::\1/g' sed -i 's/^ BlockSource::/ /g' src/qt/clientmodel.h sed -i 's/enum FlushStateMode {/enum class FlushStateMode {/g' src/validation.cpp sed -i 's/FLUSH_STATE_\(NONE\|IF_NEEDED\|PERIODIC\|ALWAYS\)/FlushStateMode::\1/g' src/validation.cpp sed -i 's/^ FlushStateMode::/ /g' src/validation.cpp -END VERIFY SCRIPT- Signed-off-by: pasta <pasta@dashboost.org>
…issues with some compilers) 43f3dec Remove enum specifier (to avoid re-declare scoped enum as unscoped) (donaloconnor) Pull request description: MSVC fails to compile with the changes made in bitcoin#10742 The problem is enum types were changed to scoped (`enum class`) but in some places `enum` as an unscoped is used. This is a very simple fix and I've tested it. Edit: Had to remove enum altogether - `enum class` doesn't compile on clang. Tree-SHA512: 13e21666243585a133c74c81249a1fa4098d6b7aa3cda06be871fa017c0ad9bb7b0725f801160b9d31678448d668718197941fd84702ebdef15128c27d92cd70
…umerations ("enum class")
0fee2b4 doc: Add note about our preference for scoped enumerations ("enum class") (practicalswift)
Pull request description:
Add note about our preference for scoped enumerations (`enum class`).
Context: bitcoin#10742
Tree-SHA512: 0ab3465c2b734240cb38a05c2f6e75f1af54207a0f1a2e8115e7b367fd37e8966a2fc0240c6d4c2c66b6677b5f367eda4f4b783bbaa419777336c17f04adff06
…oin#10742) -BEGIN VERIFY SCRIPT- sed -i 's/enum DBErrors/enum class DBErrors/g' src/wallet/walletdb.h git grep -l DB_ | xargs sed -i 's/DB_\(LOAD_OK\|CORRUPT\|NONCRITICAL_ERROR\|TOO_NEW\|LOAD_FAIL\|NEED_REWRITE\)/DBErrors::\1/g' sed -i 's/^ DBErrors::/ /g' src/wallet/walletdb.h sed -i 's/enum VerifyResult/enum class VerifyResult/g' src/wallet/db.h sed -i 's/\(VERIFY_OK\|RECOVER_OK\|RECOVER_FAIL\)/VerifyResult::\1/g' src/wallet/db.cpp sed -i 's/enum ThresholdState/enum class ThresholdState/g' src/versionbits.h git grep -l THRESHOLD_ | xargs sed -i 's/THRESHOLD_\(DEFINED\|STARTED\|LOCKED_IN\|ACTIVE\|FAILED\)/ThresholdState::\1/g' sed -i 's/^ ThresholdState::/ /g' src/versionbits.h sed -i 's/enum SigVersion/enum class SigVersion/g' src/script/interpreter.h git grep -l SIGVERSION_ | xargs sed -i 's/SIGVERSION_\(BASE\|WITNESS_V0\)/SigVersion::\1/g' sed -i 's/^ SigVersion::/ /g' src/script/interpreter.h sed -i 's/enum RetFormat {/enum class RetFormat {/g' src/rest.cpp sed -i 's/RF_\(UNDEF\|BINARY\|HEX\|JSON\)/RetFormat::\1/g' src/rest.cpp sed -i 's/^ RetFormat::/ /g' src/rest.cpp sed -i 's/enum HelpMessageMode {/enum class HelpMessageMode {/g' src/init.h git grep -l HMM_ | xargs sed -i 's/HMM_BITCOIN/HelpMessageMode::BITCOIN/g' sed -i 's/^ HelpMessageMode::/ /g' src/init.h sed -i 's/enum FeeEstimateHorizon/enum class FeeEstimateHorizon/g' src/policy/fees.h sed -i 's/enum BlockSource {/enum class BlockSource {/g' src/qt/clientmodel.h git grep -l BLOCK_SOURCE_ | xargs sed -i 's/BLOCK_SOURCE_\(NONE\|REINDEX\|DISK\|NETWORK\)/BlockSource::\1/g' sed -i 's/^ BlockSource::/ /g' src/qt/clientmodel.h sed -i 's/enum FlushStateMode {/enum class FlushStateMode {/g' src/validation.cpp sed -i 's/FLUSH_STATE_\(NONE\|IF_NEEDED\|PERIODIC\|ALWAYS\)/FlushStateMode::\1/g' src/validation.cpp sed -i 's/^ FlushStateMode::/ /g' src/validation.cpp -END VERIFY SCRIPT- Signed-off-by: pasta <pasta@dashboost.org>
…issues with some compilers) 43f3dec Remove enum specifier (to avoid re-declare scoped enum as unscoped) (donaloconnor) Pull request description: MSVC fails to compile with the changes made in bitcoin#10742 The problem is enum types were changed to scoped (`enum class`) but in some places `enum` as an unscoped is used. This is a very simple fix and I've tested it. Edit: Had to remove enum altogether - `enum class` doesn't compile on clang. Tree-SHA512: 13e21666243585a133c74c81249a1fa4098d6b7aa3cda06be871fa017c0ad9bb7b0725f801160b9d31678448d668718197941fd84702ebdef15128c27d92cd70
Rationale (from Bjarne Stroustrup's "C++11 FAQ"):