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

Unexpected behaviour of is_null - Part II #1167

Closed
phyz777 opened this issue Jul 18, 2018 · 7 comments
Closed

Unexpected behaviour of is_null - Part II #1167

phyz777 opened this issue Jul 18, 2018 · 7 comments
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@phyz777
Copy link

phyz777 commented Jul 18, 2018

The following code produces a core dump with this error message: Assertion `m_value.object->find(key) != m_value.object->end()' failed

int main() {
    nlohmann::json j;
    j["subobject"] = {{"key1", "value1"}, {"key2", "value2"}};

    const nlohmann::json &subobject = j["subobject"];

    if (!subobject["key1"].is_null()) {
        std::cout << "CHECK" << std::endl;
    } else {
        std::cout << "FAIL" << std::endl;
    }

    if (!subobject["key3"].is_null()) {
        std::cout << "CHECK" << std::endl;
    } else {
        std::cout << "FAIL" << std::endl;
    }

    return 0;
}

This is because the check inserts {"key3", null} into the object.

I'm not sure whether this behaviour is intentionally, it might at least become a pitfall for some, so I wanted to bring this to your attention.

@nlohmann
Copy link
Owner

For const json objects, operator[] has an undefined semantics if the given key is not present, see https://nlohmann.github.io/json/classnlohmann_1_1basic__json_ab2318780e5ae692039e816b6ac32c91e.html#ab2318780e5ae692039e816b6ac32c91e

@nlohmann
Copy link
Owner

More details:

  • subobject is const
  • operator[] const cannot add keys to an object, so using it with an unknown key such as "key3" has undefined behavior
  • when assertions are switched on, this undefined behavior triggers an assertion
  • always use at if you need a runtime check

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Jul 18, 2018
@phyz777
Copy link
Author

phyz777 commented Jul 18, 2018

For my purposes, it was sufficient to simply remove the const specifier.
But I'm sure all these additional information will come in handy soon or later, both for me and for others.
Thanks a lot!

@nlohmann
Copy link
Owner

Ok, thanks for checking back!

@p-i-
Copy link

p-i- commented Jan 31, 2019

json j = {
	{ "foo", 1 }
};

std::cout << j["bar"].is_null() << std::endl;
// 1

std::cout << j << std::endl;
// {"bar":null,"foo":1}

This is very unexpected behaviour.

@gregmarr
Copy link
Contributor

Where is the unexpected behavior here?

@nlohmann
Copy link
Owner

nlohmann commented Feb 1, 2019

When you have a non-const JSON value and use operator[] to access a non-existing key, a value is default-constructed at that key. This is the same behavior as std::map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

4 participants