JSON output differs between gcc and MSVC - c++

The below code snippet is using nlohmann-json library.
However the output differs between MSVC and GCC compilers (both compiled using -std=c++14).
MSVC outputs:
{"test":[]}
gcc outputs:
{"test":[[]]}
Code snippet:
#include "nlohmann/json.hpp"
#include <iostream>
int main() {
nlohmann::json output;
output["test"] = { nlohmann::json::array() };
std::cout << output.dump() << std::endl;
return 0;
}
The line output["test"] = { nlohmann::json::array() }; is triggering the difference in behavior. Removing the curly brackets around nlohmann::json::array() will align the behavior and always output {"test":[]}.
It seems the initializer list { json::array() } is interpreted by GCC as: json::array({ json::array() }) for some reason.
Could this be a potential bug in the json library, in GCC/MSVC or is there another explanation?

The nlohmann library has an already known issue with brace initialization and different compilers.
They mention this issue in the FAQ.
The workaround the library authors propose is to avoid brace initialization.

Related

As Binary literal is introduced in c++14..but it could used in C++98/C++03/C++11

Please see below code snippet it is compiled and run fine in C++03/C++11.
#include <iostream>
using namespace std;
int main(){
int a = 0b1111;
cout<<"a:: "<<a<<endl;
int var = 4;
if(var == 0b0100)
cout<<"True----------------\n";
else
cout<<"Flase---------------\n";
return 0;
}
Output:-
a:: 15
True----------------
Please help me what is the difference in C++03 and C++14 binary literal
Even Binary literal could be used in c++03/C++11.
If you use the -Wpedantic compiler option it emits warnings in C++03/C++11 mode:
warning: binary constants are a C++14 feature or GCC extension
Binary constants are a C language extension provided by GCC. Their extensions documentation says "most of them are also available in C++" which explains why it compiles.

In-class member initializer fails with VS 2013

I expected the following code to compile, but Visual Studio 2013 Update 2 gives me an error, while g++ 4.7 compiles it fine.
using std::vector;
using std::string;
struct Settings
{
vector<string> allowable = { "-t", "--type", "-v", "--verbosity" };
};
VS 2013 compile fails with:
'std::vector<std::string,std::allocator<_Ty>>::vector' : no overloaded function takes 4 arguments
If I change the member as follows then it compiles fine:
vector<string> allowable = vector<string> { "-t", "--type", "-v", "--verbosity" };
I've looked at the proposal linked from Bjarne's FAQ and I've looked at the MSDN page on completed C++11 features in VS 2013 but I'm still confused. Should it compile as is, or am I wrong and must specify the type twice?
The example that you showed is perfectly valid C++, however it doesn't work for VC++2013.
This is a known VC++2013 bug reported since 31/10/2013 and its status is still active.
However, you can surmount it by doing a work-around. As #ildjarn suggested, by simply putting an extra pair of curly braces you force initializer_list<> constructor of the std::vector to be evoked instead of its fill constructor, like the example below:
#include <string>
#include <vector>
#include <iostream>
struct Settings {
std::vector<std::string> allowable = {{"-t", "--type", "-v", "--verbosity"}};
};
int main() {
Settings s;
for (auto i : s.allowable) std::cout << i << " ";
std::cout << std::endl;
}

Why do designated initializers work in C++?

After having searched the web for a bit I've come to the conclusion that designated initializers are not part of any C++ standard, yet when compiling this code using g++ (4.7.0)
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int test[2][2] ={
[0]={1,2},
[1]={3,4},
};
for (int x = 0; x<2;x++)
{
for (int y = 0; y<2; y++)
{
cout << test[x][y] << endl;
}
}
return 0;
}
it will compile and run fine.
Am I missing something ? From everything I have read C++ should not support this type of code.
Each compiler usually has its own language extensions. It is valid as for g++ and as for example MS VC++. For example in MS VC++ you can use statement for each.
It seems you found a feature of the gcc compiler: an undocumented extension that cannot be suppressed or be warned about by using any options (such as -pedantic -std=XXXX).
If you want to be reasonably certain that your code complies with the standard, I recommend to always use a variety of compilers and make sure your code passes all of them without warnings (and use the most strict warning options). gcc and clang are free, so you can always use at least two compilers (and clang is quite good at standard compliance).

Issue with string literal and integer constant

What is it?
#include <iostream>
int main()
{
std::cout << "str"1 << '\n';
}
I think that it's impossible, but gcc compiles this code (while Comeau compiler not). Why? And what about the ouput of this code?
str"
And why it's not allowed when compiled as C code?
This appears to be a bug gcc 2.7.2 compiling C++ code as used by http://liveworkspace.org -- if you feed it "somestring"morestuffafter, it effectively converts it into "somestring\"morestuffafte" (notice that the trailing r was converted into a ").

ICC segfaulting with variable length arrays

So, when compiled with the basic icc bob.cpp -o bob and run, the following code segfaults:
#include <string>
int foo () {
return 6;
}
int main() {
std::string t[foo()];
}
The following two similar programs, however, seem to run fine.
#include <string>
int foo () {
return 6;
}
int main() {
int f = foo();
std::string t[f];
}
and
#include <string>
int foo () {
return 6;
}
int main() {
std::string t[6];
}
I'm a bit confused about what's going on. Apparently, variable length arrays are non-standard, and this was a surprise to me since I've always used g++ which supports it. However, if it's not supported by ICC, why would it compile? Also, why would example 2 "work"?
What is correct code here, and, if the first snippet is incorrect, why does it compile, and then why does it segfault?
I'm using icc (ICC) 12.0.2 20110112 on 2011 x86_64 Intel(R) Core(TM) i5.
Thanks
Well, while it is true that C++ has no variable-length arrays (C99 does though), apparently ICC does support them as an extension, since your code actually compiles (and since your second snippet actually runs without crashing).
If the first version crashes, then it must be a bug in ICC's implementation of that non-standard extension.