This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 15 days ago.
I've been using C++ for a few years, and today I saw some code, but how can this be perfectly legal?
int main(int argc, char **argv)
{
size_t size;
cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
cout << i << endl;
}
return 0;
}
Compiled under GCC.
How can the size be determined at run-time without new or malloc?
Just to double check, I've googled some and all similar codes to mine are claimed to give storage size error.
Even Deitel's C++ How To Program p. 261 states under Common Programming Error 4.5:
Only constants can be used to declare the size of automatic and static arrays.
Enlight me.
This is valid in C99.
C99 standard supports variable sized arrays on the stack. Probably your compiler has chosen to support this construct too.
Note that this is different from malloc and new. gcc allocates the array on the stack, just like it does with int array[100] by just adjusting the stack pointer. No heap allocation is done. It's pretty much like _alloca.
This is known as VLAs (variable length arrays). It is standard in c99, but gcc allows it in c++ code as an extension. If you want it to reject the code, try experimenting with -std=standard, -ansi and -pedantic options.
It is valid only in C99. Next time you may try checking your code in a reliable compiler.
It is valid C99, it is not valid C++. This is one of not a few differences between the two languages.
This Code runs in GNU GCC Compiler.
#include<bits/stdc++.h>
int main(int argc, char **argv)
{
size_t size;
std:: cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
std:: cout << i;
}
return 0;
}
You can give size to an array dynamically in if you are using Dev-Cpp compiler I have tried it
and got no error but on visual c++ and visual studio compilers it is not possible.
I think the reason is that dev-c++ assigns a positive number to the uninitialized int
and when we give it a number it is replaced by the given one.
but perhaps other compilers give null to uninitialized variables.
I recently came across a scenario where a stack-allocated array is desired. (It's a wrapper around v8, needed an array of args on every method call).
An std::vector would do heap memory allocation, whose performance is not acceptable.
Here is my solution, use template to allocation array of cases:
template<size_t Argc>
static void call(...) {
v8::Local<v8::Value> v8Args[Argc];
// use v8Args
...
}
template<typename It>
static void callV8Function(size_t argc, It argvBegin, It argvEnd,) {
// C++ don't have dynamic stack allocation (like C99 does)
// try to avoid heap-allocation...
if (argc <= 4) {
return callV8FunctionOnStack<4>(...);
} else if (argc <= 8) {
return callV8FunctionOnStack<8>(...);
} else if (argc <= 16) {
return callV8FunctionOnStack<16>(...);
} else if (argc <= 32) {
return callV8FunctionOnStack< 32>(...);
} else {
std::vector<v8::Local<v8::Value>> v8Args(argc);
// fallback to vector
}
}
(And of course, I can just do with a 32-sized array, but which is not so elegant.)
Variable Length Arrays (VLAs) are supported in the C++14 standard, which has recently been accepted, and is awaiting publication.
Related
File extension: .cpp
I have the following code:
int main() {
int N; cin >> N;
int myArray[N];
return 0;
}
I get an error when I'm trying to run that program if I input N as 1,000,000. However, when I set myArray[N] to myArray[1000000], it doesn't. Why does this happen?
int myArray[N]; is not valid in C++. This behavior was introduced in C99 but never in C++, possibly because it causes a lot of ugly stuff to happen behind the scenes in order to make it work, and it would make the generated code less efficient as a result. In fact this feature was even reversed in C11 where its support is merely optional and not mandatory anymore. Use std::vector<int> instead, or any similar standard container of your choice.
First of all VLA (variable length arrays) is an extension to C++. Compilers are supporting that since usually they support also C which has this functionality in standard.
Second problem this array is allocated on stack.
Stack has very limited size. So when your N has very big value application may crash since stack will overflow.
In this case you should use std::vector which will allocate data on heap.
Question is why array with static array size do not crash?
There can be couple reasons.
Compiler notices that array is not used and based on "As if" rule removes array.
Compiler knows size of the array at compile time, so required stack size is know. This information may be propagated to linker and application is build with bigger stack size then default value (in case of one suorce code application it may be possible). Disclaimer: this is my guessing, I didn't verified this in any form (by testing, or compiler documentation), but I've found this SO answer which confirms my suspicions.
The size of static arrays array[N] must be known at compile time.
Use std::vector for dynamic arrays:
// Example program
#include <iostream>
#include <string>
#include <vector>
int main()
{
int N; std::cin >> N;
std::cout << N << std::endl;
std::vector<int> myArray(N);
std::cout << myArray.size() << std::endl;
return 0;
}
That happens because size of static arrays must be known at compile time.
It is strongly recommended to use std::vector instead of arrays for more flexibility, and safety (this is always the answer: Use a vector if possible). You may use std::vector::reserve to request capacity be at least the length you want it to be. Use std::vector::capacity to see the current capacity.
#include <iostream>
#include <vector>
int main () {
std::vector<int> ivec;
ivec.reserve(100);
std::cout << ivec.capacity() << std::endl;
return 0;
}
Output:
100
Only if you have a very good reason to prefer arrays over vectors, you may dynamically allocate an array. Using std::shared_ptr makes this process much safer and convenient. Here's how it's done the way you want:
#include <iostream>
#include <memory>
int main () {
int N;
std::cin >> N;
std::shared_ptr<int> arr_ptr (new int[N], std::default_delete<int[]>());
for (int i = 0; i != N; ++i) {
arr_ptr.get()[i] = i * 2;
}
for (int i = 0; i != N; ++i) {
std::cout << arr_ptr.get()[i] << std::endl;
}
return 0;
}
Input:
10
Output:
0
2
4
6
8
10
12
14
16
18
That happens because, in C++, the size of static arrays declared with array[N] must be known at compile time and thus your error is propably your compiler which tells you that he must know the size inbeforehand. As stated use std::vector when you need dynamic arrays.
This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 17 days ago.
I've been using C++ for a few years, and today I saw some code, but how can this be perfectly legal?
int main(int argc, char **argv)
{
size_t size;
cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
cout << i << endl;
}
return 0;
}
Compiled under GCC.
How can the size be determined at run-time without new or malloc?
Just to double check, I've googled some and all similar codes to mine are claimed to give storage size error.
Even Deitel's C++ How To Program p. 261 states under Common Programming Error 4.5:
Only constants can be used to declare the size of automatic and static arrays.
Enlight me.
This is valid in C99.
C99 standard supports variable sized arrays on the stack. Probably your compiler has chosen to support this construct too.
Note that this is different from malloc and new. gcc allocates the array on the stack, just like it does with int array[100] by just adjusting the stack pointer. No heap allocation is done. It's pretty much like _alloca.
This is known as VLAs (variable length arrays). It is standard in c99, but gcc allows it in c++ code as an extension. If you want it to reject the code, try experimenting with -std=standard, -ansi and -pedantic options.
It is valid only in C99. Next time you may try checking your code in a reliable compiler.
It is valid C99, it is not valid C++. This is one of not a few differences between the two languages.
This Code runs in GNU GCC Compiler.
#include<bits/stdc++.h>
int main(int argc, char **argv)
{
size_t size;
std:: cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
std:: cout << i;
}
return 0;
}
You can give size to an array dynamically in if you are using Dev-Cpp compiler I have tried it
and got no error but on visual c++ and visual studio compilers it is not possible.
I think the reason is that dev-c++ assigns a positive number to the uninitialized int
and when we give it a number it is replaced by the given one.
but perhaps other compilers give null to uninitialized variables.
I recently came across a scenario where a stack-allocated array is desired. (It's a wrapper around v8, needed an array of args on every method call).
An std::vector would do heap memory allocation, whose performance is not acceptable.
Here is my solution, use template to allocation array of cases:
template<size_t Argc>
static void call(...) {
v8::Local<v8::Value> v8Args[Argc];
// use v8Args
...
}
template<typename It>
static void callV8Function(size_t argc, It argvBegin, It argvEnd,) {
// C++ don't have dynamic stack allocation (like C99 does)
// try to avoid heap-allocation...
if (argc <= 4) {
return callV8FunctionOnStack<4>(...);
} else if (argc <= 8) {
return callV8FunctionOnStack<8>(...);
} else if (argc <= 16) {
return callV8FunctionOnStack<16>(...);
} else if (argc <= 32) {
return callV8FunctionOnStack< 32>(...);
} else {
std::vector<v8::Local<v8::Value>> v8Args(argc);
// fallback to vector
}
}
(And of course, I can just do with a 32-sized array, but which is not so elegant.)
Variable Length Arrays (VLAs) are supported in the C++14 standard, which has recently been accepted, and is awaiting publication.
This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 17 days ago.
I've been using C++ for a few years, and today I saw some code, but how can this be perfectly legal?
int main(int argc, char **argv)
{
size_t size;
cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
cout << i << endl;
}
return 0;
}
Compiled under GCC.
How can the size be determined at run-time without new or malloc?
Just to double check, I've googled some and all similar codes to mine are claimed to give storage size error.
Even Deitel's C++ How To Program p. 261 states under Common Programming Error 4.5:
Only constants can be used to declare the size of automatic and static arrays.
Enlight me.
This is valid in C99.
C99 standard supports variable sized arrays on the stack. Probably your compiler has chosen to support this construct too.
Note that this is different from malloc and new. gcc allocates the array on the stack, just like it does with int array[100] by just adjusting the stack pointer. No heap allocation is done. It's pretty much like _alloca.
This is known as VLAs (variable length arrays). It is standard in c99, but gcc allows it in c++ code as an extension. If you want it to reject the code, try experimenting with -std=standard, -ansi and -pedantic options.
It is valid only in C99. Next time you may try checking your code in a reliable compiler.
It is valid C99, it is not valid C++. This is one of not a few differences between the two languages.
This Code runs in GNU GCC Compiler.
#include<bits/stdc++.h>
int main(int argc, char **argv)
{
size_t size;
std:: cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
std:: cout << i;
}
return 0;
}
You can give size to an array dynamically in if you are using Dev-Cpp compiler I have tried it
and got no error but on visual c++ and visual studio compilers it is not possible.
I think the reason is that dev-c++ assigns a positive number to the uninitialized int
and when we give it a number it is replaced by the given one.
but perhaps other compilers give null to uninitialized variables.
I recently came across a scenario where a stack-allocated array is desired. (It's a wrapper around v8, needed an array of args on every method call).
An std::vector would do heap memory allocation, whose performance is not acceptable.
Here is my solution, use template to allocation array of cases:
template<size_t Argc>
static void call(...) {
v8::Local<v8::Value> v8Args[Argc];
// use v8Args
...
}
template<typename It>
static void callV8Function(size_t argc, It argvBegin, It argvEnd,) {
// C++ don't have dynamic stack allocation (like C99 does)
// try to avoid heap-allocation...
if (argc <= 4) {
return callV8FunctionOnStack<4>(...);
} else if (argc <= 8) {
return callV8FunctionOnStack<8>(...);
} else if (argc <= 16) {
return callV8FunctionOnStack<16>(...);
} else if (argc <= 32) {
return callV8FunctionOnStack< 32>(...);
} else {
std::vector<v8::Local<v8::Value>> v8Args(argc);
// fallback to vector
}
}
(And of course, I can just do with a 32-sized array, but which is not so elegant.)
Variable Length Arrays (VLAs) are supported in the C++14 standard, which has recently been accepted, and is awaiting publication.
While trying to explain to someone why a C++ static array could not by dynamically sized, I found gcc disagreeing with me. How does the following code even compile, given that the dimension argc of array is not known at compile time?
#include <iostream>
int main(int argc, char* argv[]) {
int array[argc];
for(int i = 0; i < argc; i++) array[i] = argv[i][0];
for(int i = 0; i < argc; i++) std::cout << i << ": " << char(array[i]) << std::endl;
//for(int i = 0; i < 100; i++) { std::cout << i << " "; std::cout.flush(); array[i] = 0; }
return 0;
}
I tested this with gcc 4.2.1, and specified -Wall, without getting so much as a dirty look from the compiler. If I uncomment the last loop, I get a segfault when I assign to array[53].
I had previously placed guard arrays before and after the declaration of array, and had filled them with zeros, certain that the program must be trashing part of its stack, but gcc reordered the variables on the stack, such that I was unable to observe any data corruption.
Obviously I am not trying to get this code to "work." I'm just trying to understand why gcc even thinks it can compile the code. Any hints or explanations would be much appreciated.
Update: Thanks to all for your helpful and ridiculously fast responses!
Variable-length arrays (VLAs) are part of C99 and have been supported by gcc for a long time:
http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
Note that the use of VLAs in C90 and C++ code is non-standard, but is supported by gcc as an extension.
That's a Variable Length Array, which is part of the C99 standard. It isn't part of C++ though.
You can also use the alloca function, which also isn't standard C++, but is widely supported:
int main(int argc, char* argv[])
{
int* array = (int*) alloca( argc * sizeof(int) );
array[0] = 123;
// array automatically deallocated here. Don't call free(array)!
}
These are called variable-length arrays (available since C99) and can be declared only as an automatic variable – try putting static in front and the compiler will reject it. It just involves incrementing the stack pointer with a variable rather than with a constant offset, not more than that.
Before the introduction of variable-length arrays, allocation of variable-sized objects on the stack was done with the alloca function.
Variable-sized stack-based arrays are a G++ extension and perfectly legitimate there. They are, however, not Standard. Stack-based arrays can indeed be variably-sized on most implementations, but the Standard does not mandate this.
Arrays in C++ cannot be sized except by using a constant expression. Arrays sized via a non-const are either part of C99 or a horrible extension foisted on us by GCC. You can get rid of most of the GCC crap by using the -pedantic flag when you compile C++ code.
This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 20 days ago.
I've been using C++ for a few years, and today I saw some code, but how can this be perfectly legal?
int main(int argc, char **argv)
{
size_t size;
cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
cout << i << endl;
}
return 0;
}
Compiled under GCC.
How can the size be determined at run-time without new or malloc?
Just to double check, I've googled some and all similar codes to mine are claimed to give storage size error.
Even Deitel's C++ How To Program p. 261 states under Common Programming Error 4.5:
Only constants can be used to declare the size of automatic and static arrays.
Enlight me.
This is valid in C99.
C99 standard supports variable sized arrays on the stack. Probably your compiler has chosen to support this construct too.
Note that this is different from malloc and new. gcc allocates the array on the stack, just like it does with int array[100] by just adjusting the stack pointer. No heap allocation is done. It's pretty much like _alloca.
This is known as VLAs (variable length arrays). It is standard in c99, but gcc allows it in c++ code as an extension. If you want it to reject the code, try experimenting with -std=standard, -ansi and -pedantic options.
It is valid only in C99. Next time you may try checking your code in a reliable compiler.
It is valid C99, it is not valid C++. This is one of not a few differences between the two languages.
This Code runs in GNU GCC Compiler.
#include<bits/stdc++.h>
int main(int argc, char **argv)
{
size_t size;
std:: cin >> size;
int array[size];
for(size_t i = 0; i < size; i++)
{
array[i] = i;
std:: cout << i;
}
return 0;
}
You can give size to an array dynamically in if you are using Dev-Cpp compiler I have tried it
and got no error but on visual c++ and visual studio compilers it is not possible.
I think the reason is that dev-c++ assigns a positive number to the uninitialized int
and when we give it a number it is replaced by the given one.
but perhaps other compilers give null to uninitialized variables.
I recently came across a scenario where a stack-allocated array is desired. (It's a wrapper around v8, needed an array of args on every method call).
An std::vector would do heap memory allocation, whose performance is not acceptable.
Here is my solution, use template to allocation array of cases:
template<size_t Argc>
static void call(...) {
v8::Local<v8::Value> v8Args[Argc];
// use v8Args
...
}
template<typename It>
static void callV8Function(size_t argc, It argvBegin, It argvEnd,) {
// C++ don't have dynamic stack allocation (like C99 does)
// try to avoid heap-allocation...
if (argc <= 4) {
return callV8FunctionOnStack<4>(...);
} else if (argc <= 8) {
return callV8FunctionOnStack<8>(...);
} else if (argc <= 16) {
return callV8FunctionOnStack<16>(...);
} else if (argc <= 32) {
return callV8FunctionOnStack< 32>(...);
} else {
std::vector<v8::Local<v8::Value>> v8Args(argc);
// fallback to vector
}
}
(And of course, I can just do with a 32-sized array, but which is not so elegant.)
Variable Length Arrays (VLAs) are supported in the C++14 standard, which has recently been accepted, and is awaiting publication.