Skip to content
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

Merged
merged 2 commits into from
Apr 20, 2023
Merged

Conversation

linh2931
Copy link
Member

@linh2931 linh2931 commented Apr 19, 2023

Leap on Main branch compiles very clean on Ubuntu 20.02, with only two types and 27 instances of warnings. 26 of them are

/home/lh/work/leap-main/libraries/chainbase/include/chainbase/undo_index.hpp:524:23:    warning: comparison of integer expressions of different signedness: ‘uint64_t’ {aka ‘long unsigned int’} and ‘long int’ [-Wsign-compare]
  524 |          if( revision > std::numeric_limits<int64_t>::max() )
      |              ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is unclear why _revision was defined as int64_t not uint64_t originally. Instead of changing _revision's type which might introduce other unforeseen problems, a safer way is to change if( revision > std::numeric_limits<int64_t>::max() ) to if( revision > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) ). This static_cast is valid, since std::numeric_limits<int64_t>::max()) is a positive fixed constant.

============= Final solution ===============

During the review, @heifner suggested the right solution is to change _revision to uint64_t as original assumption about int64_t no longer holds. The final solution is changing _revision to uint64_t

Resolves #10

@linh2931 linh2931 requested review from heifner and spoonincode April 19, 2023 14:52
@@ -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()) )
Copy link
Member

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.

Copy link
Member Author

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.

@linh2931 linh2931 requested a review from heifner April 19, 2023 17:50
@@ -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;
Copy link
Member

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.

Copy link
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants