Restructure inline namespace and allow version component to be disabl… · nlohmann/json@0e61ee8

1+

# `nlohmann` Namespace

2+3+

The 3.11.0 release introduced an

4+

[inline namespace](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) to allow different parts of

5+

a codebase to safely use different versions of the JSON library as long as they never exchange instances of library

6+

types.

7+8+

## Structure

9+10+

The complete default namespace name is derived as follows:

11+12+

- The root namespace is always `nlohmann`.

13+

- The inline namespace starts with `json_abi` and is followed by serveral optional ABI tags according to the value of

14+

these ABI-affecting macros, in order:

15+

- [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) defined non-zero appends `_diag`.

16+

- [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md)

17+

defined non-zero appends `_ldvcmp`.

18+

- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by

19+

underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component)

20+

below.

21+22+

For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defined to `1` is:

23+24+

```cpp

25+

nlohmann::json_abi_diag_v3_11_2

26+

```

27+28+

## Purpose

29+30+

Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different

31+

definitions of [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This is illustrated in the diagram below.

32+33+

```plantuml

34+

[**nlohmann_json (v3.10.5)**\nJSON_DIAGNOSTICS=0] as [json]

35+

[**nlohmann_json (v3.10.5)**\nJSON_DIAGNOSTICS=1] as [json_diag]

36+

[**some_library**] as [library]

37+

[**application**] as [app]

38+39+

[library] ..|> [json]

40+

[app] ..|> [json_diag]

41+

[app] ..|>[library]

42+

```

43+44+

In releases prior to 3.11.0, mixing any version of the JSON library with different `JSON_DIAGNOSTICS` settings would

45+

result in a crashing application. If `some_library` never passes instances of JSON library types to the application,

46+

this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names.

47+48+

## Limitations

49+50+

Neither the compiler nor the linker will issue as much as a warning when translation units – intended to be linked

51+

together and that include different versions and/or configurations of the JSON library – exchange and use library

52+

types.

53+54+

There is an exception when forward declarations are used (i.e., when including `json_fwd.hpp`) in which case the linker

55+

may complain about undefined references.

56+57+

## Disabling the version component

58+59+

Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and

60+

recommends that all parts of a codebase exchanging library types be built with the same version. Users can, **at their

61+

own risk**, disable the version component of the linline namespace, allowing different versions – but not

62+

configurations – to be used in cases where the linker would otherwise output undefined reference errors.

63+64+

To do so, define [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md) to `1`.

65+66+

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

67+

section to emulate the effect of the `NLOHMANN_JSON_NAMESPACE_NO_VERSION` macro.

68+69+

!!! danger "Use at your own risk"

70+71+

Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect

72+

behavior. You have been warned!

73+

## Disabling the inline namespace completely

74+75+

When interoperability with code using a pre-3.11.0 version of the library is required, users can, **at their own risk**

76+

restore the old namespace layout by redefining

77+

[`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md) as

78+

follows:

79+80+

```cpp

81+

#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann {

82+

#define NLOHMANN_JSON_NAMESPACE_END }

83+

```

84+85+

!!! danger "Use at your own risk"

86+87+

Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You

88+

have been warned!

89+90+

## Version history

91+92+

- Introduced inline namespace (`json_v3_11_0[_abi-tag]*`) in version 3.11.0.

93+

- Changed structure of inline namespace in version 3.11.2.