ICC segfaulting with variable length arrays - c++

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.

Related

JSON output differs between gcc and MSVC

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.

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).

Why a variable length array compiles in this c++ program?

It is said that arrays are allocated at compile time, then the size must be const and available at compile time.
But the following example also works, Why?
#include <iostream>
#include <vector>
using namespace::std;
int main()
{
vector<int> ivec;
int k;
while(cin>>k)
ivec.push_back(k);
int iarr[ivec.size()];
for (size_t k=0;k<ivec.size();k++)
{
iarr[k]=ivec[k];
cout<<iarr[k]<<endl;
}
return 0;
}
Compile your code with -pedantic.
Most compilers support variable length arrays through compiler extensions.
The code works due to the compiler extensions, However as you noted the code is non standard conforming and hence non portable.

Why do statements after return change the return value?

C++ returns invalid value in the following code:
#include <iostream>
#include <vector>
using namespace std;
int f(){
vector< int * > v[2];
return 1;
v[1].push_back(NULL);
}
int main(){
cout << f();
}
The output is:
205960
When I commnet line after return, it works fine:
#include <iostream>
#include <vector>
using namespace std;
int f(){
vector< int * > v[2];
return 1;
//v[1].push_back(NULL);
}
int main(){
cout << f();
}
The output is:
1
I am using code::blocks with mingw32-g++.exe compiler. The mingw version is: gcc version 4.4.1 (TDM-2 mingw32).
Your compiler has a bug. Fortunately, it is also obsolete. You should upgrade — G++ is up to version 4.6.2, which also implements much of C++11, which is very useful.
If you choose to stick with an older compiler, that is also a decision to accept its flaws.
Edit: If you are really stuck with 4.4 (for example due to a PHB), that series is still maintained. You can upgrade to GCC 4.4.6, released just this past April.

unordered_map error in GCC

When was the unordered_map concept built into g++?
Because the following code throws an error.
#include<iostream>
#include<unordered_map>
#include<stdio.h>
using namespace std;
std::unordered_map<std::int,int> mirror;
mirror['A'] = 'A';
mirror['B'] = '#';
mirror['E'] = 3;
int main(void)
{
std::cout<<mirror['A'];
std::cout<<mirror['B'];
std::cout<<mirror['C'];
return 0;
}
I am compiling the code as follows:
g++ -c hashexample.cpp
g++ -o result hashExample.o
./result
The error I got is this:
inavalid types int[char[ for aaray subscript
What is the fix for this?
The problem is your assignment. You cannot assign values to your map in this place. C++ is not a script language.
This program works fine on my machine with gcc4.6:
#include<iostream>
#include<unordered_map>
std::unordered_map<int,int> mirror;
int main() {
mirror['A'] = 'A';
mirror['B'] = '#';
mirror['E'] = 3;
std::cout<<mirror['A'];
std::cout<<mirror['B'];
std::cout<<mirror['C'];
}
First, as mkaes points out, you cannot put assignments outside functions, so you have to put it in any, for example main.
As for unordered_map, for recent versions of gcc, if you don't want to go into C++11, you can use the TR1 version of unordered_map:
#include <tr1/unordered_map>
and the type std::tr1::unordered_map. You know, C++11 supersedes all this, but you will (at least in GCC) get this working.