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:
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_;
| ^~~~~~~~~
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?
IOUAmount
has a special representation for zero, but the default constructorIOUAmount()
has defaulted implementation, which does not land in that special representation. Some odd behavior I'm observing:A constant
IOUAmount
cannot be default constructed without braces.The error:
A default-constructed
IOUAmount
compares equal tobeast::zero
, but not to anIOUAmount
constructed withbeast::zero
. This is because the second comparison callsIOUAmount::operator== (IOUAmount const&)
, but the first callsoperator== (T const&, beast::Zero const&)
which defers to callingT::signum()
and comparing to 0.I suspect we need to manually implement the default constructor to fix both of these, but can anyone explain the first behavior?