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

basic_json::operator[key] and basic_json::value(key) return different values #4626

Closed
2 tasks
benjcarson opened this issue Jan 24, 2025 · 5 comments · Fixed by #4628
Closed
2 tasks

basic_json::operator[key] and basic_json::value(key) return different values #4626

benjcarson opened this issue Jan 24, 2025 · 5 comments · Fixed by #4628
Assignees
Labels
documentation solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@benjcarson
Copy link

Description

When parsing the following json, operator[key] and value(key) return different results despite 'key' being a valid field.

{
	"array": [
		{
			"id": 3024667086235176575
				},
		{
			"id": 5894322762133244432
				},
		{
			"id": 7912588194672682964
				},
		{
			"id": 16577926123393930376
				}
		]
}

In this case j["array"][0]["id"] != j["array"][0].value("id",0).

Reproduction steps

See minimal example below.

Expected vs. actual results

If a key exists in a json object, I would expect j[key] to return the same value as j.value(key, default).

Minimal code example

Here is a minimal program that reproduces the bug:


#include "json.hpp"
#include <string>

int main(int argc, char* argv[])
{
	std::string s = R"({
                          "array": [
                            {
                              "id": 3024667086235176575
                            },
                            {
                              "id": 5894322762133244432
                            },
                            {
                              "id": 7912588194672682964
                            },
                            {
                              "id": 16577926123393930376
                            }
                          ]
                        })";

	json j = json::parse(s);

	json& arr = j["array"];
	json& arr0 = arr[0];
	uint64_t idTest0 = arr0["id"];
	uint64_t idTest1 = arr0.value("id", 0);

	// Expected idTest0 == idTest1 == 3024667086235176575
	// Got idTest0 == 3024667086235176575
	//     idTest1 == 18446744071677218431

	return 0;
}

Error messages

Compiler and operating system

msvc (VS2022), windows 11

Library version

json-3.11.3

Validation

@gregmarr
Copy link
Contributor

It does if you pass the right default. You're passing an int as the default to value, so you're getting back an int, and then you are assigning it to a uint64_t, and your compiler isn't warning you. Pass uint64_t(0) instead and you'll get the right value.

https://www.godbolt.org/z/Wj7d8TGsE

@benjcarson
Copy link
Author

Ah thanks for the quick reply! That does fix the issue for me. Is that behaviour documented somewhere? The documentation for value() here doesn't mention that the type of the default affects how the property will be parsed.

@gregmarr
Copy link
Contributor

It doesn't affect how it's parsed, it affects the return type of the value function. I forgot that you can also specify it as a template parameter, and that's really the better way to do it.

	uint64_t idTest4 = arr0.value<uint64_t>("id", 0);

@nlohmann
Copy link
Owner

I will check if I can improve the documentation on this regard.

@nlohmann
Copy link
Owner

@benjcarson Please take a look at #4628 where I added a note and an example to avoid issues like this in the future.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Jan 25, 2025
@nlohmann nlohmann added this to the Release 3.11.4 milestone Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants