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

IOUAmount and zero #5170

Open
thejohnfreeman opened this issue Oct 30, 2024 · 0 comments
Open

IOUAmount and zero #5170

thejohnfreeman opened this issue Oct 30, 2024 · 0 comments

Comments

@thejohnfreeman
Copy link
Collaborator

IOUAmount has a special representation for zero, but the default constructor IOUAmount() has defaulted implementation, which does not land in that special representation. Some odd behavior I'm observing:

  1. A constant IOUAmount cannot be default constructed without braces.
IOUAmount const x; // error
IOUAmount y; // ok
IOUAmount const z{}; ok

The error:

/home/jfreeman/code/rippled/src/test/basics/IOUAmount_test.cpp:48:25: error: uninitialized 'const zzz' [-fpermissive]
   48 |         IOUAmount const zzz;
      |                         ^~~
In file included from /home/jfreeman/code/rippled/src/test/basics/IOUAmount_test.cpp:20:
/home/jfreeman/code/rippled/include/xrpl/basics/IOUAmount.h:43:7: note: 'const class ripple::IOUAmount' has no user-provided default constructor
   43 | class IOUAmount : private boost::totally_ordered<IOUAmount>,
      |       ^~~~~~~~~
/home/jfreeman/code/rippled/include/xrpl/basics/IOUAmount.h:60:5: note: constructor is not user-provided because it is explicitly defaulted in the class body
   60 |     IOUAmount() = default;
      |     ^~~~~~~~~
/home/jfreeman/code/rippled/include/xrpl/basics/IOUAmount.h:47:18: note: and the implicitly-defined constructor does not initialize 'int64_t ripple::IOUAmount::mantissa_'
   47 |     std::int64_t mantissa_;
      |                  ^~~~~~~~~
  1. A default-constructed IOUAmount compares equal to beast::zero, but not to an IOUAmount constructed with beast::zero. This is because the second comparison calls IOUAmount::operator== (IOUAmount const&), but the first calls operator== (T const&, beast::Zero const&) which defers to calling T::signum() and comparing to 0.
IOUAmount const z{};
z == beast::zero; // true
IOUAmount const zz(beast::zero);
z == zz; // false

I suspect we need to manually implement the default constructor to fix both of these, but can anyone explain the first behavior?

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

No branches or pull requests

1 participant