# Runtime Assertions

The code contains numerous debug assertions to ensure class invariants are valid or to detect undefined behavior.
Whereas the former class invariants are nothing to be concerned with, the latter checks for undefined behavior are to
detect bugs in client code.

## Switch off runtime assertions

Runtime assertions can be switched off by defining the preprocessor macro `NDEBUG` (see the
[documentation of assert](https://en.cppreference.com/w/cpp/error/assert)) which is the default for release builds.

## Change assertion behavior

The behavior of runtime assertions can be changed by defining macro [`JSON_ASSERT(x)`](../api/macros/json_assert.md)
before including the `json.hpp` header.

## Function with runtime assertions

### Unchecked object access to a const value

Function [`operator[]`](../api/basic_json/operator%5B%5D.md) implements unchecked access for objects. Whereas a missing
key is added in the case of non-const objects, accessing a const object with a missing key is undefined behavior (think
of a dereferenced null pointer) and yields a runtime assertion.

If you are not sure whether an element in an object exists, use checked access with the
[`at` function](../api/basic_json/at.md) or call the [`contains` function](../api/basic_json/contains.md) before.

See also the documentation on [element access](element_access/index.md).

??? example "Example 1: Missing object key"

    The following code will trigger an assertion at runtime:

    ```cpp
    #include <nlohmann/json.hpp>
    
    using json = nlohmann::json;
    
    int main()
    {
        const json j = {{"key", "value"}};
        auto v = j["missing"];
    }
    ```

    Output:

    ```
    Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144.
    ```

### Constructing from an uninitialized iterator range

Constructing a JSON value from an iterator range (see [constructor](../api/basic_json/basic_json.md)) with an
uninitialized iterator is undefined behavior and yields a runtime assertion.

??? example "Example 2: Uninitialized iterator range"

    The following code will trigger an assertion at runtime:

    ```cpp
    #include <nlohmann/json.hpp>
    
    using json = nlohmann::json;
    
    int main()
    {
        json::iterator it1, it2;
        json j(it1, it2);
    }
    ```

    Output:

    ```
    Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.
    ```

### Operations on uninitialized iterators

Any operation on uninitialized iterators (i.e., iterators that are not associated with any JSON value) is undefined
behavior and yields a runtime assertion.

??? example "Example 3: Uninitialized iterator"

    The following code will trigger an assertion at runtime:

    ```cpp
    #include <nlohmann/json.hpp>
    
    using json = nlohmann::json;
    
    int main()
    {
      json::iterator it;
      ++it;
    }
    ```

    Output:

    ```
    Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.
    ```

## Changes

### Reading from a null `FILE` or `char` pointer

Reading from a null `#!cpp FILE` or `#!cpp char` pointer in C++ is undefined behavior.  Until version 3.12.0, this
library asserted that the pointer was not `nullptr` using a runtime assertion. If assertions were disabled, this would
result in undefined behavior. Since version 3.12.0, this library checks for `nullptr` and throws a
[`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) to prevent the undefined behavior.

??? example "Example 4: Reading from null pointer"

    The following code will trigger an assertion at runtime:

    ```cpp
    #include <iostream>
    #include <nlohmann/json.hpp>
    
    using json = nlohmann::json;
    
    int main()
    {
        std::FILE* f = std::fopen("nonexistent_file.json", "r");
        try {
            json j = json::parse(f);
        } catch (std::exception& e) {
            std::cerr << e.what() << std::endl;
        }
    }
    ```

    Output:

    ```
    [json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON
    ```

## See also

- [JSON_ASSERT](../api/macros/json_assert.md) - control behavior of runtime assertions
