nlohmann / nlohmann/json

std::tuple dangling reference - implicit conversion

Open
#2,226 42 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

What is the issue you have?

I created a nlohmann::json, which I passed to a std::apply. When I wanted to get the json value at a parameter specified function (const nlohmann::json&), it referenced some undefined memory (g++).

I tried to simplify the code, when I came across the following:
std::tuple<const nlohmann::json&>::tuple(std::tuple<nlohmann::json&>&&) constructor creates a temporary object and a dangling reference.
This happens because nlohmann::json implicit conversion exists from std::tuple<nlohmann::json&>, and the tuple constructor calls the variant (3) instead of (5).

Can you provide a small but working code example?
#include <iostream>
#include <tuple>
#include <cassert>

#include "json.hpp"

int main() {
    nlohmann::json j = true;
    std::tuple<const nlohmann::json&> tup(std::forward_as_tuple(j)); 
        // std::forward_as_tuple(std::as_const(j)) works well.
    assert(&j == &std::get<0>(tup));
}

try g++

With clang it doesn't compile:
tuple:232:24: error: reference member '__value_' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object

What is the expected behavior?

g++: no assertion happens on the example code.
clang: compiles.

And what is the actual behavior instead?

g++: tuple creates a temporary object and creates a dangling reference.
clang: not compiles.

Which compiler and operating system are you using?
  • Compiler: g++ / clang (in wandbox)
  • Operating system: ubuntu based (18.04) + wandbox
Which version of the library did you use?
  • latest release version 3.7.3
  • other release - please state the version: ___
  • the develop branch

(but all version is affected)

If you experience a compilation error: can you compile and run the unit tests?
  • yes
  • no - please copy/paste the error message below

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

Start with the minimal std::tuple and std::forward_as_tuple example in the issue, then inspect json.hpp and compare the g++ and clang behavior. Run the library’s unit tests and check whether coverage exists for this implicit-conversion and dangling-reference case. Done means the behavior is resolved consistently or the limitation is clearly captured by tests and project guidance.

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
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.