145 lines
8.2 KiB
Markdown
145 lines
8.2 KiB
Markdown
# `nlohmann` Namespace
|
||
|
||
The 3.11.0 release introduced an
|
||
[inline namespace](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) to allow different parts of
|
||
a codebase to safely use different versions of the JSON library as long as they never exchange instances of library
|
||
types.
|
||
|
||
## Structure
|
||
|
||
The complete default namespace name is derived as follows:
|
||
|
||
- The root namespace is always `nlohmann`.
|
||
- The inline namespace starts with `json_abi` and is followed by several optional ABI tags according to the value of
|
||
these ABI-affecting macros, in order:
|
||
- [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) defined non-zero appends `_diag`.
|
||
- [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md)
|
||
defined non-zero appends `_ldvcmp`.
|
||
- [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md) defined non-zero appends `_dp`.
|
||
- [`JSON_BRACE_INIT_COPY_SEMANTICS`](../api/macros/json_brace_init_copy_semantics.md) defined non-zero appends
|
||
`_bics`.
|
||
- [`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md) defined non-zero appends `_psp`.
|
||
- [`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md) defined non-zero appends `_snul`.
|
||
- [`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md) defined non-zero appends `_sbu8`.
|
||
- [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md) defined non-zero
|
||
appends `_ekmo`.
|
||
- [`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md) defined non-zero appends
|
||
`_dsbs`.
|
||
- [`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) defined non-zero appends
|
||
`_dufio`.
|
||
- [`JSON_NO_SIMD`](../api/macros/json_no_simd.md) defined appends `_ns`.
|
||
- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by
|
||
underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component)
|
||
below.
|
||
|
||
For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defined to `1` is:
|
||
|
||
```cpp
|
||
nlohmann::json_abi_diag_v3_11_2
|
||
```
|
||
|
||
The name is assembled from these segments; pick a version and macros to see the resulting name:
|
||
|
||
<figure class="nj-integration-ns" data-nj-integration-ns aria-label="How the inline namespace name is assembled from its segments">
|
||
<div class="nj-integration-ns__strip" aria-live="polite">
|
||
<span class="nj-integration-ns__seg nj-integration-ns__seg--root"><code>nlohmann</code><small>root namespace</small></span>
|
||
<span class="nj-integration-ns__seg nj-integration-ns__seg--sep"><code>::</code><small> </small></span>
|
||
<span class="nj-integration-ns__seg nj-integration-ns__seg--abi"><code>json_abi</code><small>always</small></span>
|
||
<span class="nj-integration-ns__seg nj-integration-ns__seg--tag"><code>_diag</code><small>JSON_DIAGNOSTICS=1</small></span>
|
||
<span class="nj-integration-ns__seg nj-integration-ns__seg--ver"><code>_v3_11_2</code><small>version 3.11.2</small></span>
|
||
</div>
|
||
<figcaption>Version 3.11.2 with <code>JSON_DIAGNOSTICS</code> defined to <code>1</code>. ABI tags are appended in the order of the
|
||
list above, the version suffix comes last.</figcaption>
|
||
</figure>
|
||
|
||
<p class="nj-caption" markdown>The name of the inline namespace, assembled from its segments. Select a version and macros to see which ABI tags appear; a tag the chosen version does not have is disabled.</p>
|
||
|
||
## Purpose
|
||
|
||
Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different
|
||
definitions of [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This is illustrated in the diagram below.
|
||
|
||
```mermaid
|
||
graph
|
||
json["<strong>nlohmann_json (v3.10.5)</strong><br>JSON_DIAGNOSTICS=0"]
|
||
json_diag["<strong>nlohmann_json (v3.10.5)</strong><br>JSON_DIAGNOSTICS=1"]
|
||
library["<strong>some library</strong>"]
|
||
app["<strong>application</strong>"]
|
||
|
||
library --> json
|
||
app --> json_diag
|
||
app --> library
|
||
```
|
||
|
||
<p class="nj-caption" markdown>The application uses the library with `JSON_DIAGNOSTICS=1` and links `some library`, which uses the same library version with `JSON_DIAGNOSTICS=0`. Arrows point from a component to what it uses.</p>
|
||
|
||
In releases prior to 3.11.0, mixing any version of the JSON library with different `JSON_DIAGNOSTICS` settings would
|
||
result in a crashing application. If `some_library` never passes instances of JSON library types to the application,
|
||
this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names.
|
||
|
||
## Limitations
|
||
|
||
Neither the compiler nor the linker will issue as much as a warning when translation units – intended to be linked
|
||
together and that include different versions and/or configurations of the JSON library – exchange and use library
|
||
types.
|
||
|
||
There is an exception when forward declarations are used (i.e., when including `json_fwd.hpp`) in which case the linker
|
||
may complain about undefined references.
|
||
|
||
## Disabling the version component
|
||
|
||
Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and
|
||
recommends that all parts of a codebase exchanging library types be built with the same version. Users can, **at their
|
||
own risk**, disable the version component of the inline namespace, allowing different versions – but not
|
||
configurations – to be used in cases where the linker would otherwise output undefined reference errors.
|
||
|
||
To do so, define [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md) to `1`.
|
||
|
||
This applies to version 3.11.2 and above only; versions 3.11.0 and 3.11.1 can apply the technique described in the next
|
||
section to emulate the effect of the `NLOHMANN_JSON_NAMESPACE_NO_VERSION` macro.
|
||
|
||
!!! danger "Use at your own risk"
|
||
|
||
Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect
|
||
behavior. You have been warned!
|
||
|
||
## Disabling the inline namespace completely
|
||
|
||
When interoperability with code using a pre-3.11.0 version of the library is required, users can, **at their own risk**
|
||
restore the old namespace layout by redefining
|
||
[`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md) as
|
||
follows:
|
||
|
||
```cpp
|
||
#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann {
|
||
#define NLOHMANN_JSON_NAMESPACE_END }
|
||
```
|
||
|
||
!!! danger "Use at your own risk"
|
||
|
||
Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You
|
||
have been warned!
|
||
|
||
## See also
|
||
|
||
- [`NLOHMANN_JSON_NAMESPACE`](../api/macros/nlohmann_json_namespace.md) - the library namespace as macro
|
||
- [`NLOHMANN_JSON_NAMESPACE_BEGIN`, `NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md) - open and close the library namespace
|
||
- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md) - disable the version component
|
||
- [Supported Macros](macros.md) - all supported macros
|
||
- [Migration Guide](../integration/migration_guide.md) - do not hard-code the library namespace
|
||
- [`basic_json`](../api/basic_json/index.md) - the main class and all its member functions
|
||
|
||
## Version history
|
||
|
||
- Introduced inline namespace (`json_v3_11_0[_abi-tag]*`) in version 3.11.0.
|
||
- Changed structure of inline namespace in version 3.11.2.
|
||
- Added ABI tag `_dp` ([`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md)) in version 3.12.0.
|
||
- Added ABI tags `_bics` ([`JSON_BRACE_INIT_COPY_SEMANTICS`](../api/macros/json_brace_init_copy_semantics.md)), `_psp`
|
||
([`JSON_PRECISE_STREAM_POSITION`](../api/macros/json_precise_stream_position.md)), `_snul`
|
||
([`JSON_STRICT_NUL_HANDLING`](../api/macros/json_strict_nul_handling.md)), `_sbu8`
|
||
([`JSON_STRICT_BINARY_UTF8`](../api/macros/json_strict_binary_utf8.md)), `_ekmo`
|
||
([`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](../api/macros/json_use_objects_for_enum_keyed_maps.md)), `_dsbs`
|
||
([`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md)), `_dufio`
|
||
([`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md)), and `_ns`
|
||
([`JSON_NO_SIMD`](../api/macros/json_no_simd.md)) in version 3.13.0.
|