c++ weird array by user input [duplicate] - c++

This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 4 years ago.
As I know in c++ if you want to crete an array, you must give constant value for its size. But here:
int main(){
int a;
cin >> a;
int b[a] = {};
for (int i = 0; i<a ; i++){
b[i] = a;
cout << b[i];
}
return 0;
}
If i input 5
output:
55555
It works fine in a way i can't understand in dev c++. If i run this in visual studio 2017, it gives error. Can anyone explanin why?

Are you using GCC by any chance? This is a GCC extension and it's enable by default. In fact it's quite a dangerous one because it's fairly easy to cause a stack overflow on your program. It's roughly the same as using alloca().
In order to disable it, you should use a compiler flag called -Wpedantic. This will make your compiler issue a warning. (see this demonstration)
ISO C++ forbids variable length array ‘b’ [-Werror=vla]

As I know in c++ if you want to crete an array, you must give constant value for its size.
Correct. If you use a non-constant value, then the program is ill-formed. Yes, the program that you show is ill-formed.
It works fine in a way i can't understand ... Can anyone explanin why?
C++ compiler may allow compilation of an ill-formed program. This enables the compilers to extend the language. It appears that you were using a non-standard extension to C++.
This is what the GCC compiler says about your program:
warning: ISO C++ forbids variable length array 'b' [-Wvla]
int b[a] = {};
^

Related

Visual Studio Community 2019 requires a constant value inside square brackets [duplicate]

This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 2 years ago.
I've been trying to find answers for this lately, but I just can't seem to understand why the compilers for C++ that Microsoft has been using can't compile such a code :
#include<iostream>
int main()
{
int n;
std::cin >> n;
int x[n];
}
It gives those errors :
However, this code compiles on a lot of different compilers.
Could someone point me to somewhere, I couldn't find any answers for this.
See How to make an array with a dynamic size? General usage of dynamic arrays (maybe pointers too)? for discussion on the matter. Briefly, C++ requires that raw arrays have a constexpr for their size, so they it knows how much memory to allocate for it at the moment it's declared instead of at runtime after receiving user input. Some compilers I suppose are more permissive on this.
Variable length arrays are not standard C++. Some compilers provide them as a language extension but they are not portable.
This code shouldn't compile.
In C++, arrays are statically allocated and their required memory must be specified at compile time.
Hence, a user input is not a suitable value for array declaration. If you want a dynamic array, you can try using malloc like this:
#include<iostream>
int main()
{
int n;
std::cin >> n;
int* x = (int*)malloc(n*sizeof(int));
}
This way, the array is actually stored in heap, and can have any arbitrary size, changing over lifetime of the program.
Another alternative is std::vector of course.

Why I am getting garbage(unwanted) output here?

Whenever I am writing this following code, I am getting garbage(unexpected) output in some online compiler, but if I use code block then getting satisfied output. So my question is why I am getting this type of output?
for example, if I input
5 7
+ 5
- 10
- 20
+ 40
- 20
then I am getting
22 1
in the code block. But in the online compiler, it's something else.
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int have, n, i;
int kid=0;
cin>>n>>have;
int line[n];
for(i=0;i<n;i++)
{
cin>>line[i];
if(line[i]>=0)
have+=line[i];
else
{
if(have>=abs(line[i]))
have+=line[i];
else
kid++;
}
}
cout<<have<<" "<<kid<<endl;
}
The main problem I can see in your code is this:
int line[n];
This is known as a VLA (Variable Length Array) and it is not supported in C++. It is valid in C. Most compilers still allow this behaviour due to the fact that C++ is based on C, but it is not valid C++ code. In a previous question, I found out that clang supports designated initializers, when gcc and vc++ did not. The reason is because some compilers like clang, support c99-extensions by default. My point is that just because the code compiles, it doesn't mean it's always right.
If you compile with the -pedantic argument, you will see that the compiler is warning you about this being a C99 feature. Have a look at the rextester example here. From the comments below, using -pedantic-errors in the compiler flags, will prompt an error.
If you know the size of the array before run-time, then you should use a static array int line[4];, but if you don't then you need to use a dynamic array. std::vector is essentially a dynamic array that also handles memory for you. It's easy to use and very efficient. std::vector<int> line;
You can read more about the vector container here: http://www.cplusplus.com/reference/vector/vector/
Btw, I tried your code in rextester, ideone and repl.it and I got the same results: 22 1. I think what you are witnessing it undefined behaviour.
Also, you can qualify int n with constexpr and it'll be fine.
constexr int n = 200;
int line[n]; //now it's ok.
But this again means that you know the size of the array at compile time.

Why is int a[0] allowed in c++? [duplicate]

This question already has answers here:
What happens if I define a 0-size array in C/C++?
(8 answers)
Closed 6 years ago.
I find that in the declaration of an array, we cannot specify the size of it like this
int a[0];
I know, empty size array illegal in C++, but In my code, empty size array compiler allowed and give the output.
My code is here :
#include <iostream>
using namespace std;
int main()
{
int a[0];
a[0] = 10;
a[1] = 20;
cout<<a[0]<<endl;
cout<<a[1]<<endl;
return 0;
}
Output:
10
20
Online compiler link : http://code.geeksforgeeks.org/TteOmO
So, My question is, Why is int a[0] allowed GCC compiler?
It issues a warning, for example clang outputs:
warning: zero size arrays are an extension [-Wzero-length-array]
this is undefined behaviour:
a[0] = 10;
a[1] = 20;
Zero length arrays are extensions for gcc, why - you can read on it here:
https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
They are very useful as the last element of a structure that is really a header for a variable-length object:
This is actually C extension but it looks like it also is used in C++, probably to make it easier to use existing structures from C that uses this extension.
Please Look Into This
What happens if I define a 0-size array in C/C++?
If It's a good compiler it will catch that and give a warning.
but with pedantic option compiler can catch it.

Why this C++ program complies and runs in CodeBlocks [duplicate]

This question already has answers here:
Declaring an array of negative length
(3 answers)
Closed 8 years ago.
#include <iostream>
using namespace std;
int main()
{
cout<<"started "<<endl;
int n= -2;
int array[n];
array[0]=100;
array[1]=200;
cout<<array[0]<<endl;
cout<<array[1]<<endl;
cout<<"over"<<endl;
return 0;
}
Why does this compile and run? I expected a compilation error because value of n is negative.
Variable-length arrays are not a C++ feature, so this line will cause a compilation error in a compiler that is ordered to strictly adhere to the C++ specification, regardless of the value of n (unless n is const and can be determined at compile-time):
int array[n];
Likely you are using a compiler that supports variable-length arrays as an extension. Therefore, the rules regarding what is valid depend entirely on the specific compiler and compiler options, and any code that you write using this extension will not be portable to compilers that don't support this non-standard feature.

Array of non-constant size: Why does this even work? [duplicate]

This question already has answers here:
C++: Why does int array[size] work?
(3 answers)
Closed 8 years ago.
#include <iostream>
using namespace std;
int main(){
int n;
cout<<"Enter the size :";
cin>>n;
int array[n]; // I've worked some outputs and it works
return 0;
}
Is this some kind of dynamic allocation?
Why doesn't it even gives an error for 'n' to be a "const"?
Also, writing cout << array[n+5]; doesn't result in an compile time or runtime error.
I'm using Dev-C++.
Apparently one can declare variable length arrays in C99, and it seems GCC accepts then for C++ also.
Variable-length automatic arrays are allowed in ISO C99, and as an
extension GCC accepts them in C90 mode and in C++. These arrays are
declared like any other automatic arrays, but with a length that is
not a constant expression.
You learn something every day .. I hadn't seen that before.