-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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({}) gives null instead of empty object with GCC and -std=c++17 #2046
Comments
Seems this bug is related only to constructors with default arguments (and it does not must be nullptr_t) or without arguments (with #include <stdio.h>
#include <initializer_list>
struct A
{
A(std::nullptr_t = nullptr) { printf("A nullptr\n"); }
A(std::initializer_list<int>) { printf("A initializer_list\n"); }
void a(std::nullptr_t = nullptr) { printf("a nullptr\n"); }
void a(std::initializer_list<int>) { printf("a initializer_list\n"); }
};
struct B
{
B(std::nullptr_t) { printf("B nullptr\n"); }
B(std::initializer_list<int>) { printf("B initializer_list\n"); }
void b(std::nullptr_t) { printf("b nullptr\n"); }
void b(std::initializer_list<int>) { printf("b initializer_list\n"); }
};
int main()
{
A({}).a({});
B({}).b({});
return 0;
}
Maybe GCC with |
Or it treats it as |
Thanks for reporting. This is a known issue, and it seems that the compilers behave differently on how to cope with an empty initializer list. |
If that fixes the issue, this would be great! However, I am afraid that it would also break existing code as the behavior of the constructors was like this since version 1.0.0. Maybe we could add a preprocessor define to switch between old and new behavior, similar to policies in CMake? |
Sorry I deleted that comment because realized we can't do much to provide compatible fix, I don't see an option. But documentation shoud be modified for sure. It would be nice if compiler guys come here for a bit to explain this. |
But this gives either |
Here to confirm that there is different behavior on msvc as well. |
So the issue basically is that
Then the |
During the test, I found that default constructor In my tests on GCC-7.5,
Anyway, the behavior of the constructors is a little weird. |
It is not weird. C++17 changed some rules regarding 1-element and 0-element braced init lists. This is likely a compiler bug (as different ones give different results) but the usage of the API might have a different meaning in different standards too. |
@Xeverous At first, I wanted to avoid this problem by designing more sophisticated basic_json constructors, but you're right, it's caused by different compiler rules. Maybe, as nlohmann said, we can solve this problem by predefined macros. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
@misos1 Looks like this is an issue with gcc 7 only, not older, not newer: https://godbolt.org/z/z59adb |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Hello, any news on this? I don't know how to correctly handle this in my code, because sometimes it returns |
I had a similar problem related to dumping. At least there, the value |
Thanks, @SumuduLansakara, to me seems that this should be the default value for a JSON instance initialized with an empty initializer list constructor. Is a lot more reasonable if:
had the same well-defined meaning that:
|
Sorry this does not work for me, it returns |
No, this should work. Are you sure you wrote json j(json::value_t::object); rather than json j{json::value_t::object}; ? |
Wow, indeed I was using the second method, such a small difference but such a huge difference in behaviour. |
Beyond the discussion on default initialisation of |
100% agree. |
It does. |
It does not seem so. That's what brought us here (cf jupyter-xeus/xeus#309 (comment)). |
It does, at least in 3.6.0: https://godbolt.org/z/z8qWEoj34 The original report here was about
not about
|
@gregmarr the report from @SylvainCorlay was based on wrong info from me. We had still a few |
I saw, thanks for the confirmation. |
Readme says:
But seems when using GCC with
-std=c++17
json({})
actually gives null. Without-std=c++17
or with-std=c++14
or any other version it works. On clang it works with any version.Seems there is some problem with overload resolution because
basic_json(std::nullptr_t = nullptr)
is called instead ofbasic_json(initializer_list_t init, bool type_deduction = true...
. It works after I explicitly set second parameter totrue
.g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
develop
branch?version 3.7.0
The text was updated successfully, but these errors were encountered: