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

assertion on runtime causes program to stop when accessing const json with missing key #2392

Closed
1 of 3 tasks
codeaddicted opened this issue Sep 9, 2020 · 5 comments
Closed
1 of 3 tasks

Comments

@codeaddicted
Copy link

Hi,

i just stumbled upon something i think might be a bug but am unsure about.

when accessing a const nlohmann::json &j object and using a missing key the library will fail with an assertion which causes the whole program to stop (assertion not catchable).

Here is an example how to reproduce it.

#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main() {
  try {
    const json j{
        {"foobar", "barfoo"},
        {"boofar", "blubber"}
    };

    std::cout << j.dump(2) << std::endl; // check that it
    std::cout << j["fubber"] << std::endl;
  } catch ( json::exception &e ) {
    std::cout << "JSON Exception: " << e.what() << std::endl;
  } catch (std::exception &e ) {
    std::cout << "Std Exception: " << e.what() << std::endl;
  }

  std::cout << "Successfully Finished!" << std::endl;
}

i know i should check for a keys existence with j.count(<key>) but shouldn't the access on a missing key throw an exception of type json::out_of_range (or similar) so it is catchable instead of asserting and therefore aborting the whole program?

The error it produces is:

nlohmann_assert_error_test: /tmp/tmp.HiflujZ3cJ/./nlohmann-json/include/nlohmann/json.hpp:3735: const value_type& nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::operator[](T*) const [with T = const char; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>; nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::const_reference = const nlohmann::basic_json<>&; nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::value_type = nlohmann::basic_json<>]: Assertion `m_value.object->find(key) != m_value.object->end()' failed.

Which compiler and operating system are you using?

  • Compiler: g++ (Debian 8.3.0-6) 8.3.0
  • Operating system: Debian 10.4

Which version of the library did you use?

current develop (@1bcabd9e83ebc2d04b5767c7f51bf385e80398d6)

  • latest release version 3.9.1
  • other release - please state the version: ___
  • the develop branch
@t-b
Copy link
Contributor

t-b commented Sep 9, 2020

Only at does bounds checking, see https://nlohmann.github.io/json/api/basic_json/at/. The index operator does no bounds checking.

@codeaddicted
Copy link
Author

Well is there a reason why or just "because"?

@nlohmann nlohmann removed the kind: bug label Sep 9, 2020
@nlohmann
Copy link
Owner

nlohmann commented Sep 9, 2020

This is not a bug, but a feature. Unchecked access is apparently faster than bounded-checked access, and accessing a nonexisting element of a const object is undefined behavior. This is described in https://nlohmann.github.io/json/api/basic_json/operator%5B%5D/. A more detailed description can be found in https://nlohmann.github.io/json/features/element_access/unchecked_access/ . Please let me know if further information is needed.

@gregmarr
Copy link
Contributor

gregmarr commented Sep 9, 2020

See #2111 for discussion of a possible solution to this.

@codeaddicted
Copy link
Author

Thank you for clarifying this. I know understand why the function behaves like this. Closing this issue.

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

4 participants