nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
41.98k stars 6.62k forks source link

parse returns desired array contained in array when JSON text begins with square bracket on gcc 7.5.0 #2339

Closed sbashford closed 4 years ago

sbashford commented 4 years ago

What is the issue you have?

When compiled with gcc 7.5.0, passing a JSON array to parse returns an array containing the desired array. This is not the same behavior on clang 10.0.0 where the desired array is instead returned.

Please describe the steps to reproduce the issue.

on macOS 10.15.6 with cmake 3.18.1 and brew 2.4.9 in a directory containing the CMakeLists.txt and main.cpp listed below:

  1. brew install gcc@7
  2. cmake -S . -B build -DCMAKE_CXX_COMPILER=/usr/local/bin/g++-7
  3. cmake --build build
  4. ./build/example

Can you provide a small but working code example?

# CMakeLists.txt
include(FetchContent)

set(JSON_BuildTests
    OFF
    CACHE INTERNAL "")
FetchContent_Declare(
  json
  GIT_REPOSITORY
    https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent
  GIT_TAG v3.9.0)
FetchContent_MakeAvailable(json)

add_executable(example main.cpp)
target_link_libraries(example nlohmann_json::nlohmann_json)
// main.cpp
#include <nlohmann/json.hpp>
#include <iostream>
int main() {
  const auto example{nlohmann::json::parse(R"([{"pi": 3.141}])")};
  std::cout << example;
}

What is the expected behavior?

[{"pi":3.141}]

And what is the actual behavior instead?

[[{"pi":3.141}]]

Which compiler and operating system are you using?

Which version of the library did you use?

nlohmann commented 4 years ago

The issue is that braces are interpreted as array or object, so json j {1}; creates [1] rather than 1. You can fix the example by changing

const auto example{nlohmann::json::parse(R"([{"pi": 3.141}])")};

to

const auto example = nlohmann::json::parse(R"([{"pi": 3.141}])");

I have no idea how to fix this without breaking existing code. Maybe an option like we introduced for implicit conversions?

sbashford commented 4 years ago

That solves my use case. Thanks for your quick reply.

The behavior appears to be different on clang 10.0.0. But this is not an issue when using an assignment as you've described.

nlohmann commented 4 years ago

Duplicate of #2311.