nlohmann / nlohmann/json

String type change breaks C++ type matching

Open
#2,649 18 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind: bug state: help needed
Dominant language
C++
Stars
50.6k
Forks
7.5k
Avg merge
4d 17h
Merged PRs (30d)
58

Description

Usually when one of template parameters is changed, reference to new type cannot be implicitly converted to reference to old type. However for some reason this is not true for nlohmann::json. I tried to change std::string to my custom string class, and it turned out that references to both types are compatible for compiler. Here is example code which demonstrates this problem. It uses std::wstring instead of std::string:

#include <json.hpp>

template <
    template <typename U, typename V, typename... Args> class ObjectType = std::map,
    template <typename U, typename... Args> class ArrayType              = std::vector,
    class StringType = std::wstring, class BooleanType = bool,
    class NumberIntegerType = std::int64_t, class NumberUnsignedType = std::uint64_t,
    class NumberFloatType = double, template <typename U> class AllocatorType = std::allocator,
    template <typename T, typename SFINAE = void> class JSONSerializer = nlohmann::adl_serializer>
using MyBasicJson = nlohmann::basic_json<
    ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType,
    NumberFloatType, AllocatorType, JSONSerializer>;

using MyJson = MyBasicJson<>;

void load(const nlohmann::json& json);
//void load(const MyJson& json);

void test(MyJson* json)
{
    load(*json);
}

During compilation I should get error that parameter passed to load() has incorrect type. However this code compiles cleanly. I tried to use gcc 10.2, clang 10.0, both compiles this code without any complain. I use nlohmann::json 3.9.1. I compiled it on CentOS and Ubuntu using following command:

g++ -c -o dupa.o test.cpp -O3 -Wall -Wextra -Werror -std=c++11 -I.

I played a bit with this code trying to create minimum example. I found that when removed include and copied forward declarations from json.hpp to my file, g++ reported error as expected. So it looks that something is wrong in other part of json.hpp.

Initially I thought that this may be some gcc error, but clang also does not complain, so this is unlikely.

Which compiler and operating system are you using?

gcc 10.2 on CentOS7 (installed from RedHat SCL packages), clang 10.0 on Ubuntu Ubuntu 20.04.2 LTS

Which version of the library did you use?
  • latest release version 3.9.1
  • other release - please state the version: ___
  • the develop branch

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the provided MyBasicJson example against json.hpp with the stated C++11 compiler command, then inspect the basic_json declarations and conversions involved in the call to load. Compare this behavior with the forward-declaration-only version; done means the incompatible string type behavior is understood and covered by a suitable regression check.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.