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

puzzled implicit conversions #1692

Closed
studywithallofyou opened this issue Jul 30, 2019 · 7 comments
Closed

puzzled implicit conversions #1692

studywithallofyou opened this issue Jul 30, 2019 · 7 comments
Labels
kind: bug state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated

Comments

@studywithallofyou
Copy link

studywithallofyou commented Jul 30, 2019

  • evironment:

vs2017 c++17 windows7 64 develop branch

  • code:
long long lnum = 327221437;
nlohmann::json a;
a["num1"] = 327220625;
nlohmann::json b;
b["num2"] = 900000;
if (lnum - a["num1"] > b["num2"])
{
    cout << lnum << endl;
    cout << a["num1"] << endl;
    cout << b["num2"] << endl;
    cout << lnum - a["num1"] << endl;
    cout << lnum - a["num1"].get<long long>() << endl;
}
  • result:
327221437
327220625
900000
327221292
812

could you tell me why lnum - a["num1"] is not same as lnum - a["num1"].get<long long>() but cout << a["num1"] << endl; is correct

@nickaein
Copy link
Contributor

nickaein commented Jul 30, 2019

Note that implicit conversions from JSON are discouraged, you should avoid a["num1"] and use a["num1"].get<T>() or a["num1"].get_to(target_var) instead.

Based on the result of lnum - a["num1"], I guess the implicit conversion to int gets picked up for a["num1"] which corrupts the original number.

In cout << a["num1"] << endl; however, there is no type deduction magic involved and no implicit conversion happens. The operator<< gets called which in turn calls dump_integer that basically dumps the integer value to a string buffer and can handle integers as big as long long.

@studywithallofyou
Copy link
Author

studywithallofyou commented Jul 31, 2019

Note that implicit conversions from JSON are discouraged, you should avoid a["num1"] and use a["num1"].get<T>() or a["num1"].get_to(target_var) instead.

Based on the result of lnum - a["num1"], I guess the implicit conversion to int gets picked up for a["num1"] which corrupts the original number.

In cout << a["num1"] << endl; however, there is no type deduction magic involved and no implicit conversion happens. The operator<< gets called which in turn calls dump_integer that basically dumps the integer value to a string buffer and can handle integers as big as long long.

Thanks very much.
I think if implicit conversions is uncertainty, it will be error and can not build success. Make user use get<T>() forcibly like Jsoncpp it is not allowed to write like a["num1"]. Must be a["num1"].asInt64() instead.

@nlohmann
Copy link
Owner

nlohmann commented Aug 3, 2019

For what it's worth, I cannot even compile the line

std::cout << lnum - a["num1"] << std::endl;

in Clang

main.cpp:18:27: Use of overloaded operator '-' is ambiguous (with operand types 'long long' and 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long, unsigned long long, double, std::allocator, adl_serializer>::value_type' (aka 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long, unsigned long long, double, std::allocator, adl_serializer>'))

@studywithallofyou
Copy link
Author

For what it's worth, I cannot even compile the line

std::cout << lnum - a["num1"] << std::endl;

in Clang

main.cpp:18:27: Use of overloaded operator '-' is ambiguous (with operand types 'long long' and 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long, unsigned long long, double, std::allocator, adl_serializer>::value_type' (aka 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long, unsigned long long, double, std::allocator, adl_serializer>'))

My project is in visual studio 2017 and build with vs defaul tool msbuild. I didn't test with clang.

Fail also with gcc/g++ when I test. It is only OK complile with vs.

@studywithallofyou
Copy link
Author

How to do for the bug. Should I close it?

@igoloe
Copy link

igoloe commented Aug 25, 2019

Ain't that some kind of operator precedence problem in combination with implicit conversions?

Putting parenthesis around the minus operation in the stream operation makes the execution order not collide wirh stream operator overloads.

@stale
Copy link

stale bot commented Sep 24, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Sep 24, 2019
@stale stale bot closed this as completed Oct 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated
Projects
None yet
Development

No branches or pull requests

4 participants