json icon indicating copy to clipboard operation
json copied to clipboard

Different results on Linux vs Windows when using json["str"].push_back({json::object})

Open jtl7913 opened this issue 4 months ago • 9 comments

Description

For the following code, I get different results for when running the compiled code on Linux vs Windows.

std::ifstream ifs(targetFile);
json original_jf = json::parse(ifs);
json jf_toParse;
jf_toParse["aaa"] = original_jf["aaa"];
json jf;
bool retainElement = false;
for (auto &[arrayElementKey, arrayElementValue] : jf_toParse["aaa"].items())
{
    retainElement = false;
    for (auto &[elementKey, elementValue] : arrayElementValue.items())
    {
        if (elementKey == "bbb" || elementKey == "ccc")
        {
            /// don't have to worry about this being a string. This is error checked prior to this.
            if (elementValue)
            {
                retainElement = true;
            }
        }
    }
    if (retainElement)
    {
        jf["aaa"].push_back({arrayElementValue});
    }
}

std::ofstream outfile (resultFile, std::ios::out | std::ios::binary); 
outfile << std::setw(4) << jf << std::endl;

On Linux, I get the following for the resultFile :

{
    "aaa": [
        [
            {
                "aRandomStr": "randomStr1",
                "bbb": true,
                "randomStrTwo": "randomStr2"
            }
        ],
        [
            {
                "aRandomBool": true,
                "aRandomStr": "randomStr3",
                "bbb": true,
                "randomStrTwo": "randomStr4"
            }
        ],
        [
            {
                "aRandomBool": true,
                "aRandomStr": "randomStr5",
                "bbb": true,
                "randomStrTwo": "randomStr6"
            }
        ],
        [
            {
                "aRandomStr": "randomStr7",
                "ccc": true,
                "randomStrTwo": "randomStr8"
            }
        ],
        [
            {
                "aRandomStr": "randomStr8",
                "ccc": true,
                "randomStrTwo": "randomStr9"
            }
        ]
    ]
}

On Windows, I get the following for the resultFile :

{
    "aaa": [
        {
            "aRandomStr": "randomStr1",
            "bbb": true,
            "randomStrTwo": "randomStr2"
        },
        {
            "aRandomBool": true,
            "aRandomStr": "randomStr3",
            "bbb": true,
            "randomStrTwo": "randomStr4"
        },
        {
            "aRandomBool": true,
            "aRandomStr": "randomStr5",
            "bbb": true,
            "randomStrTwo": "randomStr6"
        },
        {
            "aRandomStr": "randomStr7",
            "ccc": true,
            "randomStrTwo": "randomStr8"
        },
        {
            "aRandomStr": "randomStr8",
            "ccc": true,
            "randomStrTwo": "randomStr9"
        }
    ]
}

I feel like I shouldn't be getting different results for this when the only difference is the operating system and compiler being used. Linux/gcc11 vs Windows/msvc142

Reproduction steps

I put this in the description. I tried to be as specific as possible. For the targetFile please use a targetFile that has the following content: Please define resultFile as well.

{
    "aaa": [
        {
            "aRandomStr": "randomStr1",
            "DDD": true,
            "randomStrTwo": "randomStr2"
        },
        {
            "aRandomStr": "randomStr1",
            "bbb": true,
            "randomStrTwo": "randomStr2"
        },
        {
            "aRandomBool": true,
            "aRandomStr": "randomStr3",
            "bbb": true,
            "randomStrTwo": "randomStr4"
        },
        {
            "aRandomBool": true,
            "aRandomStr": "randomStr5",
            "bbb": true,
            "randomStrTwo": "randomStr6"
        },
        {
            "aRandomStr": "randomStr7",
            "ccc": true,
            "randomStrTwo": "randomStr8"
        },
        {
            "aRandomStr": "randomStr8",
            "ccc": true,
            "randomStrTwo": "randomStr9"
        }
    ]
}

Expected vs. actual results

I feel like the results I get for Windows/msvc142 are correct and the Linux/gcc11 results via resultFile are wrong/bugged.

Minimal code example

// You'll still have to define `targetFile` to some file that you filled with the contents I put in the Repoduction Steps.
// You'll have to define your `resultFile` as well.


std::ifstream ifs(targetFile);
json original_jf = json::parse(ifs);
json jf_toParse;
jf_toParse["aaa"] = original_jf["aaa"];
json jf;
bool retainElement = false;
for (auto &[arrayElementKey, arrayElementValue] : jf_toParse["aaa"].items())
{
    retainElement = false;
    for (auto &[elementKey, elementValue] : arrayElementValue.items())
    {
        if (elementKey == "bbb" || elementKey == "ccc")
        {
            /// don't have to worry about this being a string. This is error checked prior to this.
            if (elementValue)
            {
                retainElement = true;
            }
        }
    }
    if (retainElement)
    {
        jf["aaa"].push_back({arrayElementValue});
    }
}

std::ofstream outfile (resultFile, std::ios::out | std::ios::binary); 
outfile << std::setw(4) << jf << std::endl;

Error messages

# No error messages. Just different/bad results on Linux vs Windows

Compiler and operating system

Various Linux (redhat and suse) systems with gcc11 VERSUS Windows 10/11 with msvc142

Library version

Noticed bug/issue with 3.9.1. Upgraded to 3.12.0 and the same bug/issue exists. Latest develop branch commit (4106af8) also yielded the same results.

Validation

jtl7913 avatar Aug 20 '25 19:08 jtl7913

See the very first entry in the FAQ. https://json.nlohmann.me/home/faq/

gregmarr avatar Aug 20 '25 20:08 gregmarr

@nlohmann It seems like we get an issue report for this about every two months or so. Seems like we should add something to the top of the issue template to tell people to look at the first FAQ entry before reporting an issue.

gregmarr avatar Aug 20 '25 20:08 gregmarr

@gregmarr EXCELLENT. Thank you :)

Changing jf["aaa"].push_back({arrayElementValue}); to jf["aaa"].push_back(arrayElementValue); fixed my issue!

Y'all have a great one! Love this library.

jtl7913 avatar Aug 20 '25 20:08 jtl7913

@gregmarr Good point. I'll see if I can find some wording for this.

nlohmann avatar Aug 20 '25 20:08 nlohmann

This issue has been marked as stale because it has been open for 90 days without activity. If this issue is still relevant, please add a comment or remove the "stale" label. Otherwise, it will be closed in 10 days. Thank you for helping us prioritize our work!

github-actions[bot] avatar Nov 19 '25 00:11 github-actions[bot]

@nlohmann Did we add anything to the template?

gregmarr avatar Nov 19 '25 15:11 gregmarr

@nlohmann Did we add anything to the template?

What do you mean? The stale bot?

nlohmann avatar Nov 19 '25 15:11 nlohmann

@nlohmann It seems like we get an issue report for this about every two months or so. Seems like we should add something to the top of the issue template to tell people to look at the first FAQ entry before reporting an issue.

@gregmarr Good point. I'll see if I can find some wording for this.

gregmarr avatar Nov 19 '25 15:11 gregmarr

Ahh, I see. Yes, it's already FAQ No. 1 and the FAQ should be probably be mentioned more prominently.

nlohmann avatar Nov 19 '25 17:11 nlohmann