Skip to content

Conversion of Json::Value to long int is ambiguous #64

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

Closed
orodbhen opened this issue Nov 7, 2014 · 8 comments
Closed

Conversion of Json::Value to long int is ambiguous #64

orodbhen opened this issue Nov 7, 2014 · 8 comments

Comments

@orodbhen
Copy link

orodbhen commented Nov 7, 2014

Trying to copy a Json::Value object to a long int fails to compile, because Json::Uint64 and Json::Int64 are mapped to unsigned long int and long int, respectively.

On Linux/Unix systems, at least, these should instead be mapped to uint64_t and int64_t, which will always be 64 bit.

Also note that these typedefs (int64_t and uint64_t) don't work either with the Json::Value constructor, because they are typdefed to long int when __WORDSIZE == 64. They do work when __WORDSIZE == 32, because then they map to long long int, just like Json::Int64.

@BillyGoto
Copy link

I think everybody is annoyed by the specificity of the Value numeric
constructors. Maybe the situation could be improved by introducing template
constructors Value(const T& v), enabled iff T can convert to Uint64 and
Int64 respectively. The metaprogramming is tricky but can be encapsulated.

On Thursday, November 6, 2014, orodbhen [email protected] wrote:

Trying to copy a Json::Value object to a long int fails to compile,
because Json::Uint64 and Json::Int64 are mapped to unsigned long int and
long int, respectively.

On Linux/Unix systems, at least, these should instead be mapped to
uint64_t and int64_t, which will always be 64 bit.

Also note that these typedefs (int64_t and uint64_t) don't work either
with the Json::Value constructor, because they are typdefed to long int
when __WORDSIZE == 64. They do work when __WORDSIZE == 32, because then
they map to long long int, just like Json::Int64.


Reply to this email directly or view it on GitHub
#64.

ǝnɥɐuop ʎllıq

@orodbhen
Copy link
Author

orodbhen commented Nov 7, 2014

Using templates would improve automatic type-casting in general.

At the very least, I think the Json numerical types should map to the architecture independent types provided on Unix/Linux, instead of the traditional int, long, short, etc.

@BillyDonahue
Copy link
Contributor

MSVC has supported "long long" since MSVC 2010:
http://msdn.microsoft.com/en-us/library/hh567368.aspx#c99table

We can do better than __int64 these days. I'm not sure "unsigned __int64" is guaranteed to mean anything. If __int64 were a typedef instead of a macro, it wouldn't compile at all.

Microsoft doesn't specify how it's implemented:
http://msdn.microsoft.com/en-us/library/eke1xt9y.aspx

update: nevermind, they actually do use "unsigned __int8" etc in their docs.
http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx

@cdunn2001
Copy link
Contributor

Personally, I would rather use a factory for Value, and a setter for each type. I don't like implicit type-casting. But I guess people enjoy the convenience of the ctors.

But I would also store the value as a string and convert to/from numeric types via wrappers. That allows arbitrary-precision floats and infinitely long integers. It also avoids some CPU work for numbers that are never actually accessed after being read.

I would change jsoncpp dramatically, but the preserved comments seem to be the differentiating feature for this library. So I guess convenience is paramount.

I'd rather not make the decision on this one.

@cdunn2001
Copy link
Contributor

I've pulled your commits into Billy's accept_all_arithmetic_types branch for historical reference. See #66.

@orodbhen
Copy link
Author

orodbhen commented Jun 2, 2015

just checking back to see if any work has been done on this. I find jsoncpp to be very unfriendly to programming with templates.

Currently, I use a wrapper I created that maps the type of the output buffer to the correct jsoncpp type. It's original purpose was to provide a C interface to jsoncpp, but I use it in C++ as well.

It would be nice, though, to have a more generalized interface for C++ that works with templates. I'd like to contribute, but first I need to know how the maintainers want to implement it.

@cdunn2001
Copy link
Contributor

Maybe some sort of wrapper? You can derive your own CharReader and StreamWriter to operate on your data-types. But if you want to templatize Json::Value, you might be better off forking the whole project.

@TuNguyen89
Copy link

Today I'm get the different result of function Value::UInt64 Value::asUInt64() const

I have Value["key"] = 18446744073709551616 (Max unsigned 64 bit + 1)
Then the Value["key"] converted to real.
When I use the function value.asUInt64() I get different value for the same compiler but different architect (amd64 vs arm64)

In amd64, 2^64 is returned.
In arm64, 0 is return.

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

5 participants