Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected deserialization difference between Mac and Linux #2338

Closed
1 of 3 tasks
wbuck opened this issue Aug 4, 2020 · 4 comments
Closed
1 of 3 tasks

Unexpected deserialization difference between Mac and Linux #2338

wbuck opened this issue Aug 4, 2020 · 4 comments
Labels
kind: bug solution: duplicate the issue is a duplicate; refer to the linked issue instead state: needs more info the author of the issue needs to provide more details

Comments

@wbuck
Copy link

wbuck commented Aug 4, 2020

What is the issue you have?

When deserializing the following json from a file on macOS

{
    "SaveAllImages": true,
    "SaveOnlyFailedImages": false,
    "RedThreshold": 215,
    "MaxRedThreshold": 255,
    "BlueThreshold": 215,
    "MaxBlueThreshold": 255,
    "BlobFilterArea": true,
    "BlobMinAreaPx": 2000,
    "BlobMaxAreaPx": 6000,
    "BlobMinThreshold": 10,
    "BlobMaxThreshold": 10000,
    "BlobFilterCircularity": true,
    "BlobMinCircularity": 0.6,
    "BlobMaxCircularity": 1.0
}

I get an object (which is expected)

{
    "SaveAllImages": true,
    "SaveOnlyFailedImages": false,
    "RedThreshold": 215,
    "MaxRedThreshold": 255,
    "BlueThreshold": 215,
    "MaxBlueThreshold": 255,
    "BlobFilterArea": true,
    "BlobMinAreaPx": 2000,
    "BlobMaxAreaPx": 6000,
    "BlobMinThreshold": 10,
    "BlobMaxThreshold": 10000,
    "BlobFilterCircularity": true,
    "BlobMinCircularity": 0.6,
    "BlobMaxCircularity": 1.0
}

When I run this same code, using the same json file in a docker container running Debian I get an array (unexpected)

 [{
     "SaveAllImages": true,
     "SaveOnlyFailedImages": false,
     "RedThreshold": 215,
     "MaxRedThreshold": 255,
     "BlueThreshold": 215,
     "MaxBlueThreshold": 255,
     "BlobFilterArea": true,
     "BlobMinAreaPx": 2000,
     "BlobMaxAreaPx": 6000,
     "BlobMinThreshold": 10,
     "BlobMaxThreshold": 10000,
     "BlobFilterCircularity": true,
     "BlobMinCircularity": 0.6,
     "BlobMaxCircularity": 1.0
}]

This of course causes an exception be to thrown:

[json.exception.type_error.306] cannot use value() with array

Can you provide a small but working code example?

Reading the file

    std::ifstream file{ config };
    if ( !file.is_open( ) )
    {
        throw create_error( 
            "Get configuration error: Failed to open file {}\n", config );
    }

   // This succeeds.
    try { return json::parse( file ); }
    catch( const json::exception& ex )
    {
        throw create_error( 
            "Get configuration error: Deserialization failed {}\n", ex.what( ) );
    } 

Reading a property

// This throws the exception specified above.
double threshold{ json_reader.value( "BlueThreshold", 215.0 ) };

What is the expected behavior?

I expect deserialization to be the same for both platforms.

And what is the actual behavior instead?

On macOS I get a json object back, on Linux I get an array back.

Which compiler and operating system are you using?

  • Compiler: g++ (Linux) and clang (macOS)

  • Operating system:

  • Host: macOS Catalina

  • Container: Debian

Which version of the library did you use?

  • latest release version 3.9.0
  • other release - please state the version: 3.7.3 (Installed from vcpkg)
  • the develop branch

I'm currently exposing the json file to the container via osxfs

@wbuck wbuck added the kind: bug label Aug 4, 2020
@nlohmann
Copy link
Owner

nlohmann commented Aug 5, 2020

There is a known (and still open) issue that when you initialize json variables with braces, they trigger the initializer list constructor and return an array. For instance json j {1}; creates the JSON array [1] instead of just the number 1.

Can you please double check whether it's really parsing the value and not a brace initialization?

@nlohmann nlohmann added the state: needs more info the author of the issue needs to provide more details label Aug 5, 2020
@wbuck
Copy link
Author

wbuck commented Aug 5, 2020

@nlohmann Oh I see, so if I'm doing something like this:

json get_config( std::string_view path )
{
    std::ifstream file{ config };
    return json::parse( file );
}

void some_func( )
{
    // This could trigger the ctor taking an initializer list?
    auto config{ get_config( "/path/to/json" ) };
}

Maybe it's time I stop using brace initialization...

@wbuck
Copy link
Author

wbuck commented Aug 5, 2020

Yes this issue is related to 2311
I can close this issue if you'd like.

@nlohmann
Copy link
Owner

nlohmann commented Aug 5, 2020

Duplicate of #2311.

@nlohmann nlohmann closed this as completed Aug 5, 2020
@nlohmann nlohmann added the solution: duplicate the issue is a duplicate; refer to the linked issue instead label Aug 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug solution: duplicate the issue is a duplicate; refer to the linked issue instead state: needs more info the author of the issue needs to provide more details
Projects
None yet
Development

No branches or pull requests

2 participants