-
Notifications
You must be signed in to change notification settings - Fork 6
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
Fix comparison of different signedness warning #10
Conversation
include/chainbase/undo_index.hpp
Outdated
@@ -521,7 +521,7 @@ namespace chainbase { | |||
if( _undo_stack.size() != 0 ) | |||
BOOST_THROW_EXCEPTION( std::logic_error("cannot set revision while there is an existing undo stack") ); | |||
|
|||
if( revision > std::numeric_limits<int64_t>::max() ) | |||
if( revision > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) ) |
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 think this an ok quick fix to get rid of all the warnings. However, I think the correct fix is to change _revision
to be an uint64_t
and modify revision()
and undo_stack_revision_range()
to return uint64_t
. The old version of chainbase used revision -1
as a flag. See https://github.com/EOSIO/chainbase/blob/759ca20e908b60e54eed463d0b2889f6e2108e71/include/chainbase/chainbase.hpp#L292
That is no longer the case, so this code could be simplified and made clearer as revision can no longer be negative.
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.
Thanks @heifner for the background information! I was afraid to change _revision
to uint64_t
.
I will do the right fix in this PR. This will prevent future confusions, remove all the related static_cast and make code cleaner.
@@ -897,7 +894,7 @@ namespace chainbase { | |||
rebind_alloc_t<Allocator, node> _allocator; | |||
rebind_alloc_t<Allocator, old_node> _old_values_allocator; | |||
id_type _next_id = 0; | |||
int64_t _revision = 0; | |||
uint64_t _revision = 0; |
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 was a little concerned this might cause a consensus failure. However, according to https://en.cppreference.com/w/cpp/language/types Range of values
section:
Prior to C++20, the C++ Standard allowed any signed integer representation, [...] [including] ones' complement or sign-and-magnitude.
However, all C++ compilers use two's complement representation, and as of C++20, it is the only representation allowed by the standard...
Therefore the memory layout of int64_t
and uint64_t
are the same in C++20 and should be the same in pre-C++20 if all compilers use two's complement.
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.
Thanks for digging into this further. As _revision
has not reached std::numeric_limits<int64_t>::max()
yet, its representation in both int64_t
and uint64_t
are the same.
Leap on Main branch compiles very clean on Ubuntu 20.02, with only two types and 27 instances of warnings. 26 of them are
It is unclear why
_revision
was defined asint64_t
notuint64_t
originally. Instead of changing_revision
's type which might introduce other unforeseen problems, a safer way is to changeif( revision > std::numeric_limits<int64_t>::max() )
toif( revision > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) )
. This static_cast is valid, sincestd::numeric_limits<int64_t>::max())
is a positive fixed constant.============= Final solution ===============
During the review, @heifner suggested the right solution is to change
_revision
touint64_t
as original assumption aboutint64_t
no longer holds. The final solution is changing_revision
touint64_t
Resolves #10