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).
practicalswift force-pushed
on Jul 4, 2017
practicalswift force-pushed
on Jul 4, 2017
fanquake added the label
Refactoring
on Jul 5, 2017
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:
@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.
Only three static_cast<int>(RPCErrorCode) remain, and since they are explicit they should not cause any surprises (as opposed to implicit conversions).
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.
ArielLorenzo-Luaces approved
practicalswift force-pushed
on Jul 5, 2017
practicalswift force-pushed
on Jul 5, 2017
practicalswift force-pushed
on Jul 6, 2017
practicalswift force-pushed
on Jul 6, 2017
practicalswift force-pushed
on Jul 6, 2017
practicalswift force-pushed
on Jul 15, 2017
practicalswift force-pushed
on Jul 15, 2017
practicalswift
commented at 5:38 pm on July 15, 2017:
contributor
Rebased!
practicalswift force-pushed
on Jul 17, 2017
practicalswift force-pushed
on Jul 17, 2017
practicalswift force-pushed
on Jul 18, 2017
practicalswift
commented at 4:04 am on July 18, 2017:
contributor
Rebased again! :-)
practicalswift force-pushed
on Jul 18, 2017
practicalswift force-pushed
on Jul 18, 2017
practicalswift force-pushed
on Jul 18, 2017
practicalswift force-pushed
on Jul 24, 2017
practicalswift force-pushed
on Jul 24, 2017
practicalswift force-pushed
on Jul 24, 2017
practicalswift force-pushed
on Jul 30, 2017
practicalswift force-pushed
on Jul 30, 2017
practicalswift force-pushed
on Jul 30, 2017
practicalswift force-pushed
on Jul 30, 2017
practicalswift force-pushed
on Aug 1, 2017
practicalswift
commented at 9:23 am on August 1, 2017:
contributor
Rebased! :-)
practicalswift force-pushed
on Aug 1, 2017
practicalswift force-pushed
on Aug 3, 2017
practicalswift
commented at 1:00 pm on August 3, 2017:
contributor
Anyone willing to review? :-)
promag
commented at 1:41 pm on August 3, 2017:
member
0*** Commit 1 1commit f849a1579df933b4ddefc2486e1459831d693b66 2 Cast from HTTPStatusCode to int where required
3 4*** Commit 2 5commit a338ad0ae69aadc1d0f4d62cfd2e8dae0317c769 6 scripted-diff: Convert HTTPStatusCode to a scoped enum (C++11)
7 8-BEGIN VERIFY SCRIPT- 9 sed -i 's/enum HTTPStatusCode/enum class HTTPStatusCode/g' src/rpc/protocol.h
10 sed -i 's/\(HTTP_OK\|HTTP_BAD_REQUEST\|HTTP_UNAUTHORIZED\|HTTP_FORBIDDEN\|HTTP_NOT_FOUND\|HTTP_BAD_METHOD\|HTTP_INTERNAL_SERVER_ERROR\|HTTP_SERVICE_UNAVAILABLE\)/HTTPStatusCode::\1/g' src/bitcoin-cli.cpp src/httprpc.cpp src/httpserver.cpp src/rest.cpp
11 sed -i 's/int nStatus/HTTPStatusCode status/g' src/httprpc.cpp
12 sed -i 's/nStatus/status/g' src/httprpc.cpp
13-END VERIFY SCRIPT-1415*** Commit 316commit b4bc819716981f80108f852c93c245a35159d3a817 Add WriteReply(HTTPStatusCode, ...) in addition to WriteReply(int, ...)
Commits should be atomic if possible, but the combination of a scripted-diff and two dependent manual commits seems be tricky to get atomic. Do you have any suggestions on how to fix it? A unified diff would be ideal :-)
MarcoFalke
commented at 2:24 pm on August 3, 2017:
member
Would it be possible to reduce the number of commits, as each of them has to be reviewed separately?
practicalswift force-pushed
on Aug 3, 2017
jgarzik
commented at 2:32 pm on August 3, 2017:
contributor
This change appears to add a lot of redundancy: It makes that which can be deduced by the compiler explicit at each use site (kinda the opposite of the auto trend).
practicalswift force-pushed
on Aug 3, 2017
practicalswift
commented at 2:46 pm on August 3, 2017:
contributor
@jgarzik Is the argument that strongly typed enums should never be used (generally), or that strongly typed enums are not appropriate in these specific cases (this PR)? :-)
TheBlueMatt
commented at 2:47 pm on August 3, 2017:
member
Strong Concept ACK, explicit is always better than implicit. Maybe start with adding this to the style guide and requiring it for new code?
practicalswift force-pushed
on Aug 3, 2017
practicalswift force-pushed
on Aug 3, 2017
practicalswift force-pushed
on Aug 3, 2017
ryanofsky
commented at 3:08 pm on August 3, 2017:
member
@jgarzik Is the argument that strongly typed enums should never be used (generally), or that strongly typed enums are not appropriate in these specific cases (this PR)? :-)
A simple way to get rid of some of the redundancy would be to remove prefixes from the enum values (e.g. HTTPStatusCode::HTTP_UNAUTHORIZED -> HTTPStatusCode::UNAUTHORIZED, RPCErrorCode::RPC_PARSE_ERROR -> RPCErrorCode::PARSE_ERROR, etc)
practicalswift
commented at 4:02 pm on August 3, 2017:
contributor
@ryanofsky Good idea! Should I do that in this PR or in a follow up PR? :-)
practicalswift
commented at 4:03 pm on August 3, 2017:
contributor
@MarcoFalke Good point! Squashed into three commits!
MarcoFalke
commented at 4:13 pm on August 3, 2017:
member
@practicalswift The suggestion to remove the prefix could be done in this pull. I imagine it easily couples with the scripted diff.
practicalswift
commented at 4:14 pm on August 3, 2017:
contributor
@MarcoFalke Great! I’ll fix a scripted-diff for that!
practicalswift force-pushed
on Aug 8, 2017
practicalswift force-pushed
on Aug 8, 2017
practicalswift force-pushed
on Aug 8, 2017
practicalswift force-pushed
on Aug 8, 2017
practicalswift
commented at 12:07 pm on August 8, 2017:
contributor
I’ve now added a scripted-diff which removes redundant prefixes from enum values as suggested by @MarcoFalke. Please review :-)
practicalswift renamed this:
Use scoped enumerations (C++11, "enum class")
scripted-diff: Use scoped enumerations (C++11, "enum class")
on Aug 15, 2017
practicalswift force-pushed
on Aug 15, 2017
practicalswift
commented at 11:49 am on August 15, 2017:
contributor
Rebased!
practicalswift force-pushed
on Aug 15, 2017
practicalswift force-pushed
on Aug 16, 2017
practicalswift force-pushed
on Aug 20, 2017
practicalswift
commented at 4:13 pm on August 20, 2017:
contributor
Rebased!
TheBlueMatt
commented at 1:43 am on August 21, 2017:
member
Hmm, I dont believe contrib/devtools/commit-script-check.sh supports multiple scripts in a single commit. Personally I’m fine with them being independant commits and dont really mind a 20-commit PR for something like this, but if you want to keep it squashed, you could just make it all one script and put comments in it.
practicalswift force-pushed
on Aug 21, 2017
practicalswift
commented at 8:05 am on August 21, 2017:
contributor
@TheBlueMatt Ah, thanks for letting me know! I’ve now put it into one script with comments.
practicalswift force-pushed
on Aug 21, 2017
practicalswift force-pushed
on Aug 22, 2017
practicalswift
commented at 8:20 am on August 22, 2017:
contributor
Rebased! Anyone willing to review? Perhaps @laanwj? :-)
TheBlueMatt
commented at 8:37 pm on August 22, 2017:
member
Notes on the first script: why the extra “([^:])” in the second sed? It seems to run identically without it?
The s/== FLUSH_STATE_/== FlushStateMode::FLUSH_STATE_/g replace seems redundant.
It would be nice to make it build after the first commit. You could probably just move the two fix commits to before the first scripted-diff.
practicalswift force-pushed
on Aug 22, 2017
practicalswift
commented at 9:21 pm on August 22, 2017:
contributor
The ([^:]) was left from an earlier attempt at making the scripted-diff idempotent :-) Now removed.
Removed the redundant FLUSH_STATE_-replacement and re-arranged the commits.
Looks good now? :-)
practicalswift force-pushed
on Sep 10, 2017
practicalswift force-pushed
on Sep 10, 2017
practicalswift
commented at 7:58 am on September 11, 2017:
contributor
Rebased! :-)
practicalswift
commented at 9:26 pm on September 18, 2017:
contributor
Anyone willing to review? :-)
practicalswift force-pushed
on Sep 29, 2017
practicalswift force-pushed
on Oct 2, 2017
practicalswift force-pushed
on Oct 2, 2017
practicalswift force-pushed
on Oct 2, 2017
practicalswift force-pushed
on Oct 2, 2017
practicalswift
commented at 7:25 am on October 3, 2017:
contributor
Rebased!
practicalswift
commented at 7:26 am on October 3, 2017:
contributor
@laanwj Is there any chance that this one will make it into 0.16? If so, I’ll keep it updated/rebased :-)
MarcoFalke
commented at 8:30 am on October 3, 2017:
member
@practicalswift I guess so. It just needs someone to review ;)
sipa
commented at 9:29 am on October 3, 2017:
member
Can you do the cast to int using a C-style cast? Those are preferred for primitive types, and a bit more concise to read.
practicalswift force-pushed
on Oct 3, 2017
practicalswift force-pushed
on Oct 3, 2017
practicalswift
commented at 11:45 am on October 4, 2017:
contributor
Now using C-style casts for primitive types as suggested by @sipa :-)
laanwj
commented at 4:07 pm on October 11, 2017:
member
@practicalswift I’m sorry but there are too many all-over-the-place “cosmetic” changes like this lately, it kind of tires me, trying to focus my limited time on PRs that add functionality or fix bugs. So no, I don’t expect to get around to reviewing this any time soon.
practicalswift force-pushed
on Nov 9, 2017
practicalswift force-pushed
on Nov 9, 2017
practicalswift
commented at 9:50 pm on November 9, 2017:
contributor
@laanwj I do not see this PR as cosmetic. Traditional C++ enumerations cause real problems (name clashes, implicit conversion to int, inability to forward declare, etc.) and I would argue that C++11 enum classes are strictly better from a secure coding/“minimize surprises” perspective.
Hope somebody is willing to review and ACK this scripted-diff PR :-)
practicalswift force-pushed
on Nov 16, 2017
practicalswift
commented at 9:33 pm on November 16, 2017:
contributor
Rebased! :-)
practicalswift force-pushed
on Nov 21, 2017
practicalswift
commented at 8:38 am on November 21, 2017:
contributor
Rebased! :-)
practicalswift force-pushed
on Dec 13, 2017
practicalswift force-pushed
on Dec 21, 2017
practicalswift
commented at 12:37 pm on December 21, 2017:
contributor
Rebased!
practicalswift force-pushed
on Jan 11, 2018
practicalswift
commented at 9:22 pm on January 11, 2018:
contributor
Rebased again! :-)
@MarcoFalke@TheBlueMatt – you seemed to be positive to this PR. Would you mind reviewing? :-)
practicalswift force-pushed
on Jan 28, 2018
practicalswift force-pushed
on Jan 28, 2018
practicalswift
commented at 11:20 am on January 28, 2018:
contributor
Rebase number 12 performed! :-)
MarcoFalke
commented at 4:29 pm on January 28, 2018:
member
Since this doesn’t get any review, you might want to leave everything that requires a static_cast for later. And regardless, the goal of enum class is to be type safe, whereas for an enum that represents ints, type safety is still preferable, but maybe not as important, since the tradeoff is to blaster the code with static_casts
practicalswift force-pushed
on Jan 29, 2018
practicalswift
commented at 8:28 am on January 29, 2018:
contributor
@MarcoFalke Good idea! Removed changes to HTTPStatusCode, RPCErrorCode and Base58Type which all required static_cast:s. The scripted-diffs and the resulting changes are now free from static_cast:s and should be easier to review. Thanks!
practicalswift force-pushed
on Feb 8, 2018
practicalswift
commented at 9:15 am on February 8, 2018:
contributor
Rebase number 13 performed! :-)
practicalswift force-pushed
on Feb 12, 2018
practicalswift
commented at 3:16 pm on February 12, 2018:
contributor
Rebase number 14 performed! :-)
MarcoFalke
commented at 6:16 pm on February 12, 2018:
member
This is a metadata mirror of the GitHub repository
bitcoin/bitcoin.
This site is not affiliated with GitHub.
Content is generated from a GitHub metadata backup.
generated: 2024-12-18 15:12 UTC
This site is hosted by @0xB10C More mirrored repositories can be found on mirror.b10c.me