Constant value error in array declaration - c++

While writing my code on Visual Studio 2022, I came across the error (E0028) that the expression must have a constant value in line 11.
#include <iostream>
using namespace std;
int main()
{
int n;
cout<<"Enter"<<endl;
cin>>n;
int a[n]; //error line
for(int i = 0; i<n; i++)
{
cin>>a[i];
}
for(int i = 0; i<n; i++)
{
cout<<" "<<a[i];
}
return 0;
}
But when I put the same code in any online compiler, it worked fine. How does this happen? Also how to resolve the issue in Visual Studio 2022.
What I have tried:
I think that the best way to deal with this is dynamic array allocation using vectors, but I would like to hear your views. Also, why don't we have the same error in online compilers?

The size of an array variable must be compile time constant. n is not compile time constant, and hence the program is ill-formed. This is why the program doesn't compile, and why you get the error "expression must have a constant value".
But when I put the same code in any online compiler, it worked fine. How does this happen
This happens because some compilers extend the language and accept ill-formed programs.
how to resolve the issue in Visual Studio 2022.
Don't define array variables without compile time constant size.
I think that the best way to deal with this is dynamic array allocation using vector
You think correctly. Use a vector.

In the C99 version of the C standard variable-length arrays are allowed,
No version of C++ allows them;
When you said online compiler did you mean ideone.com?
ideone as I know uses gcc of Cygwin, there C++ (gcc 8.3) as well as C++14 (gcc 8.3) allows varaiable length array which is non-standard
#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
a[i]=i*i;
cout<<a[i]<<endl;
}
return 0;
}

Related

Is there is any way that i can define user input as my string array length? [duplicate]

I am trying to create this simple program which displays the data of the array back to the user again.. I want to create a variable length array. In this program the user is first asked the number of elements of the array followed by the data.
The problem is that in some of the IDE this code runs completely fine but in others it gives the error that variable length array is not allowed.... So what is correct?
void main()
{
int t;
cin>>t;
int ar[t];
for(int i=0;i<t;i++)
{
cin>>ar[i];
}
for(int i=0;i<t;i++)
{
cout<<ar[i]<<"\t";
}
}
For eg. This doesn't work in Turbo C++... But runs in this IDE's
http://www.tutorialspoint.com/compile_cpp11_online.php
https://www.codechef.com/ide
Standard C++ does not support variable length arrays. Some implementations provide it as an extension but as you have already found out, relying on them makes for non-portable code.
I recommend you use a std::vector instead. It works with pure standard C++.
int size;
if (!(std::cin >> size) || (size < 0))
throw std::invalid_argument {"bad size"};
std::vector<int> numbers (size);
In GCC and Clang, you can use the -pedantic compiler switch to turn off any non-standard extensions. This will help you avoid accidentally writing non-portable code. Of course, you should also compile with -Wall, -Wextra and -Werror.

Some codes are not running properly in DEV C++

I have been using DEV C++ for the last 2 months and never faced such an issue. But today when I am running the follow code, the execution screen is displaying nothing.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
int a[n];
cout<<"ENTER THE ELEMENTS OF THE ARRAY:";
for(int i=0; i<n; i++){
cin>>a[i];
}
const int N = 1e6+2;
int idx[N];
for(int i=0;i<N;i++){
idx[i]=-1;
}
int minidx = INT_MAX;
for(int i=0; i<n; i++){
if(idx[a[i]]!=-1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]]=i;
}
}
if(minidx == INT_MAX){
cout<<"NO REPEATING ELEMENT FOUND";
}
else{
cout<<"REPEATING ELEMENT FOUND AT:"<<minidx+1;
}
return 0;
}
This is the screenshot of the output screen.
Pls suggest me a solution to this problem.
I have been using DEV C++ for the last 2 months
Notice that DEV C++ is an old, non-standard conforming, and buggy compiler.
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
int a[n];
What would happen if your user has input -1234? Arrays cannot have negative dimensions, and your code did not test that!
You deserve using a better C++ compiler
E.g. the ones (GCC or Clang) inside a Debian distribution, with a good source code editor such as GNU emacs and some good build automation tool like GNU make.
#include <bits/stdc++.h>
is wrong and non standard conforming, and is slowing down your compilation.
const int N = 1e6+2;
int idx[N];
This is not reasonable: you want more than four millions bytes on your call stack, which is often limited to a megabyte. My guess is that you are experimenting some stack overflow for your automatic variable idx
Consider using standard C++ containers, and upgrade your compiler to a decent one.
I recommend using a recent GCC (at end of 2020, this means GCC 10) compiler as g++ -Wall -Wextra -g since you want all warnings and debug info. You could even use static analysis options to g++
Once you got no warnings, use the GDB debugger to understand the behavior of your program.
Read a good C++ programming book
See this C++ reference, the documentation of your C++ compiler, and of your debugger.
Consider using tools like the Clang static analyzer on your code.
Refer to a recent C++ draft standard, such as n4659. Be afraid of undefined behavior. Take inspiration from existing C++ open source code on github or gitlab.
In a few months, if so allowed, consider coding your GCC plugin to find some bugs in your programs. Be aware of Rice's theorem.
DevC++ seems now supported by Embarcadero: https://github.com/Embarcadero/Dev-Cpp/releases checked it, and it is looking ok enough. I will assume that you are not using the 1991 version of this IDE and the compiler it came with; Of course, if you want to use it with Windows 98 then the old version might be an option,
Anyhow, I will try to list the issues in your code. Most of them are a trap for beginners:
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
in this part, you are not forcing flushing before asking for user input. It is always a good practice to flush before user-input. How this can be an issue? Long story short you can get for example C/C++ printf() before scanf() issue
solution: c++ force std::cout flush (print to screen).
Let's continue you are using Variable-length array (VLA) here which is not supported by C++ stdandard,
int a[n];
You can check for more Why aren't variable-length arrays part of the C++ standard?
Recommend using std::vector a(n); there which it will allocate in the heap. If yo want the allocation in the stack, within standards then you either need to wait for "dynarray" (which may never be available in C++) or switch to C...
const int N = 1e6+2;
int idx[N];
for(int i=0;i<N;i++){
idx[i]=-1;
}
in the code below, you are trying to allocate a gigabyte of buffer in the stack. I suspect this is the reason why your program is not running properly. If you want a cheap hack then you can convert this allocation to "static int idx[N];" which will move this buffer to the heap. Beware using a static variable is not a good practice at all and not recommending it. Recommend either "new []" or "vector" there too,
for(int i=0; i<n; i++){
if(idx[a[i]]!=-1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]]=i;
}
}
idx[a[i]] has no boundary check. you should check the boundary for both arrays.
First of all, this is a security leak and a very bad-way of writing a program: Example of a buffer overflow leading to a security leak
Also, this part looks like it has a logic issue: Withing the boundary all the "idx" elements should be "-1" so you should never get into the else-condition (in a normal way)

"Expression must have constant value" CPP [duplicate]

#include <iomanip>
#include <iostream>
#include <Windows.h>
using namespace std;
template <class T>
void sort(int n, T a[]){
for(i=0;i<n-1;i++){
for(j=i;j<n;j++){
if(a[i] > a[j]){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}
void main(){
int size;
cout<<" Please input the amount of numbers you would like to sort"<<endl;
cin>>size;
int Amta[size];
for(int i=0; i<size; i++){
cout<<"Please enter the "<<size+1<< "number";
cin>>Amta[i];
}
Sleep(100000);
}
I am trying to get the how many numbers the user would like to input from the user and store it in the variable size.
But when I initialize array Amta[size] I get the following compile errors:
Expression must have constant value
and
C2057: expected constant expression" compile error.
You can't enter a non-constant value between the brackets when you declare your array:
int Amta[size];
Since you're getting size from the user, the compiler can't tell ahead of time how much memory it needs for Amta. The easiest thing to do here (especially for an exercise) is to just choose a relatively large value and make that the constant allocation, like:
int Amta[1024];
And then if you want to be careful (and you should) you can check if (size > 1024) and print an error if the user wants a size that's beyond the pre-allocated bounds.
If you want to get fancy, you can define Amta with no pre-set size, like int *Amta; and then you allocate it later with malloc:
Amta = (int *)malloc(sizeof(int) * size);
Then you must also free Amta later, when you're done with it:
free(Amta);
C++ doesn't allow variable length arrays. The size must be a constant. C99 does support it so if you need you can use a C99 compliant compiler. Some compilers like GCC and Clang also support VLA as an extension in C++ mode
But if C++ is a must then you can use alloca (or _alloca on Windows) to allocate memory on stack and mimic the C99 variable length array behavior
Amta = (int *)alloca(sizeof(int) * size);
This way you don't need to free the memory after going out of scope because the stackframe will automatically be restored. However you need to be very careful while using this. It's still better to use std::vector in C++ for these purposes

Can we create variable length arrays in c++

I am trying to create this simple program which displays the data of the array back to the user again.. I want to create a variable length array. In this program the user is first asked the number of elements of the array followed by the data.
The problem is that in some of the IDE this code runs completely fine but in others it gives the error that variable length array is not allowed.... So what is correct?
void main()
{
int t;
cin>>t;
int ar[t];
for(int i=0;i<t;i++)
{
cin>>ar[i];
}
for(int i=0;i<t;i++)
{
cout<<ar[i]<<"\t";
}
}
For eg. This doesn't work in Turbo C++... But runs in this IDE's
http://www.tutorialspoint.com/compile_cpp11_online.php
https://www.codechef.com/ide
Standard C++ does not support variable length arrays. Some implementations provide it as an extension but as you have already found out, relying on them makes for non-portable code.
I recommend you use a std::vector instead. It works with pure standard C++.
int size;
if (!(std::cin >> size) || (size < 0))
throw std::invalid_argument {"bad size"};
std::vector<int> numbers (size);
In GCC and Clang, you can use the -pedantic compiler switch to turn off any non-standard extensions. This will help you avoid accidentally writing non-portable code. Of course, you should also compile with -Wall, -Wextra and -Werror.

Array size declaring dynamically in c and c++

I'm passing the array size dynamically through a variable named size, it's working fine in c but not in c++. Please tell me the reason, Thanks in advance.
#include <iostream>
#include <stdlib.h>
using namespace std;
int size;
int main(int argc, char *argv[])
{
int i ;
int *a[size];
cout<<"Enter size";
cin >> size;
for(i =0; i < size ;i++)
{
cout<<"Enter value:" ;
cin>>a[i] ;
}
for(i=0 ; i < size; i++)
{
cout<<a[i]<< " ";
}
system("PAUSE");
return 0;
}
I have executed the same program with proper I/O changes, its executed properly.
Also please help me in understanding how compiler is behaving in this case at the time of array declaration.
Please tell me the reason
The reason is that C++ doesn't have variable-length arrays. Perhaps you are looking for std::vector<int> (likely) or new int (unlikely).
Also please help me in understanding how compiler is behaving in this case at the time of array declaration.
Just like it behaves in any other case: it parses the source text and outputs machine code of which the semantics correspond to that of the source code. It's just that the size of a variable-length array is not hard-coded as a constant, instead it is stored in a register or on the stack (like some sort of "variable"), and size calculations (pointer arithmetic, in particular) are performed agains that stored value.
Your code tries to allocate an amount of memory from an uninitialized variable size. Its value is assigned only later:
int a[size];
/* ... */
cin >> size;
If you switch the order of these statements, it might do what you want, if your C++ compiler has an extension for variable length arrays. A more portable and generally preferable solution would be:
cin >> size;
std::vector<int> a(size);
Edit: You probably want an int[] not *int[].
You cannot create variable length arrays in c++. try using vectors instead
There are no VLAs in C++.
If you want to write your code to be used in a C++ project, then write your code in C++ (use std::vector instead of VLAs) or write your code in C, compile it with a C compiler and use your linker to link to it from your C++ project.
int *a[size]; by this statement you want to create a array of size size , but you have not initialized the variable size.C++ doesn't support variable length array.You can do it by this:
int size;
cin>>size;
int *a[size];
or just use STL vector which allocates memory dynamically.
vector<int>a;
and to put value in the vector just push back the values
a.push_back(56);
For more about vector check out this link