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

json becomes empty for unknown reason #2470

Closed
1 of 3 tasks
congard opened this issue Nov 13, 2020 · 5 comments
Closed
1 of 3 tasks

json becomes empty for unknown reason #2470

congard opened this issue Nov 13, 2020 · 5 comments
Labels
solution: invalid the issue is not related to the library

Comments

@congard
Copy link

congard commented Nov 13, 2020

It is a really strange issue: when I pass nlohmann::json to function it (json) becomes empty for an unknown reason. Moreover, if I just copy this function and rename it, everything ok.

Code below uses glm. It is in a separate header that is included in others.

template<typename T>
T import(const nlohmann::json &config) {
    if (config.empty()) // true
        return T();

    T glmType;
    auto array = reinterpret_cast<typename T::value_type *>(&glmType);

    for (glm::length_t i = 0; i < sizeof(T) / sizeof(array[0]); i++)
        array[i] = config[i];

    return glmType;
}

Example:

json pos = {1, 2, 3};
assert(!pos.empty());
vec3 m_pos = import<vec3>(pos); // returns empty vector, but if I copy & rename function 'import' - everything will be ok

What is the expected behavior?

config mustn't be empty

And what is the actual behavior instead?

config for unknown reason becomes empty

Which compiler and operating system are you using?

  • Compiler: GCC 10.2.0 / Clang 10.0.1
  • Operating system: Linux (ArchLinux)

Which version of the library did you use?

  • latest release version 3.9.1
  • other release - please state the version: ___
  • the develop branch
@gregmarr
Copy link
Contributor

What is empty here, pos or m_pos? What is the definition of the vec3 type?

@gregmarr
Copy link
Contributor

If changing from

template<typename T>
T import(const nlohmann::json &config) {

to

template<typename T>
T other_import(const nlohmann::json &config) {

makes it work, then you likely have another import function somewhere that is being used instead. Have you run this under a debugger or added some printf statements to make sure it's actually getting into the function that you think it is?

@congard
Copy link
Author

congard commented Nov 13, 2020

makes it work, then you likely have another import function somewhere that is being used instead

No, I mean that if I copy this function, rename copied one to something different, and use it, then it will work as expected. If I just rename import to something else, nothing will change.

For example, this function is used in multiple files, and config will be empty here

template<typename T>
T import_0(const nlohmann::json &config) {

But this used only in one file, and it will work as expected

template<typename T>
T import_1(const nlohmann::json &config) {

Also, these functions located in the unique namespace, so, I cannot use other function instead of import


Moreover, if I put nlohmann::json to simple wrapper like

struct JsonHelper {
    nlohmann::json json;

    JsonHelper(nlohmann::json inJson);
}

JsonHelper::JsonHelper(nlohmann::json inJson)
    : json(move(inJson))
{
    // see initializer list above
}

then the json will be null, and helper.json.empty() inside function import will produce an exception:

Program received signal SIGSEGV, Segmentation fault.
0x00007fa445614230 in nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > >::empty (this=0x0) at /home/congard/Development/algine-examples/lib/algine/contrib/nlohmann/json.hpp:21506
21506	switch (m_type)

Code:

JsonHelper jh = json {1.0f, 2.0f, 3.0f};
//cout << jh.json.dump() << "\n"; // [1.0,2.0,3.0]
vec3 v = GLMTransferrer::import<vec3>(jh); // GLMTransferrer - just namespace

But if I uncomment 2nd line

JsonHelper jh = json {1.0f, 2.0f, 3.0f};
cout << jh.json.dump() << "\n"; // [1.0,2.0,3.0]
vec3 v = GLMTransferrer::import<vec3>(jh);

then will be different exception:

terminate called after throwing an instance of 'nlohmann::detail::type_error'
  what():  [json.exception.type_error.305] cannot use operator[] with a numeric argument with number

and

template<typename T>
T import(const JsonHelper &jsonHelper) {
    const auto &config = jsonHelper.json;

    printf("%i\n", config.size()); // prints 1

I really don't understand what the black magic is going on, looks like a compiler bug.

@nlohmann
Copy link
Owner

Can you provide a self-contained minimal code example?

@congard
Copy link
Author

congard commented Nov 15, 2020

Problem solved. I noticed, that in all source files except one was #define GLM_FORCE_CTOR_INIT. Thus, the implementation in the last source file was different (different ctors), and because of this, I bumped into such strange issue. There are no any issues in nlohmann::json, I tried to pass std::string instead, and it was empty too:

template<typename T>
T import(const std::string &config) {

@congard congard closed this as completed Nov 15, 2020
@nlohmann nlohmann added solution: invalid the issue is not related to the library and removed kind: bug labels Nov 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: invalid the issue is not related to the library
Projects
None yet
Development

No branches or pull requests

3 participants