boostorg / json

A C++11 library for parsing and serializing JSON to and from a DOM container in memory.

Home Page:https://boost.org/libs/json

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

as_uint64 can be misanderstood

RoyBellingan opened this issue · comments

Would you considered adding a link to the doc that explain why as_uint64 will fail except when the number is bigger than INT64_MAX ?
Is at the bottom of the doc, and else is not very clear why

	auto raw = R"({
 "x" : 1
})";

	auto       jv = bj::parse(raw);
	auto       x  = jv.as_object()["x"].as_uint64();

terminate called after throwing an instance of 'boost::wrapexcept<boost::system::system_error>' 
what(): value is not a std::uint64_t number [boost.json:34 at ../boost_json/include/boost/json/value.hpp:2675:54 in function 'ui
nt64_t& boost::json::value::as_uint64()']

ATM the function is here

if( is_uint64() )

Maybe just a note to add that should be used normally but instead to_number.

It might be time for us to reevaluate our treatment of int64/uint64 and allow accessing int64 as uint64 and vice versa.

This is not undefined behavior because https://eel.is/c++draft/basic.lval#11.2 allows it, although it may require using an uint64 field in the union in both cases (because accessing an inactive field is still UB, even if the type matches.)

commented

What would be the benefit, though? Users would have to check kind() anyway, and handle the other kinds someway.

You don't need to check kind() before using as_ functions.

commented

So, what do you think should be the behaviour for

value jv = -1;
std::cout << jv.as_uint64() << '\n';

Throws.

Getting this "right" is a bit tricky, but I think it can be done. as_int64 throws for uint64 values that don't fit into int64. as_uint64 throws for negative int64 values. The const overloads just return a const reference. The non-const overloads adjust the kind to match the called function (if necessary) and then return a non-const reference.

commented

That's just a limited version of to_number. Why not use to_number then?

commented

Also, I'm not sure how I feel about as_int64 changing the value's kind.