I am reading a book saying that in C++ you can't do this:
int array_size = 3;
int array[array_size];
Then I tried it with gcc,but it didn't complain at all(exception warned about unused array).
Also I read about this question.The 4th answer says that you can use something like this:char someCondition[ condition ];To me the condition would only be known until runtime,so the whole thing seems really confounding to me.Can anyone help explain this?
Thanks,G
If You are using a C++ compiler it works because most of the C++ compilers provide a compiler extension that supports Variable Length arguments(VLA).
If You are using a C compiler it works because the standard allows it.
In C++, VLA are not allowed by the C++ Standard, so any usage of it through compiler extensions will make your code non portable.
C++ provides std::vector or std::array(C++11) which satisfy all the requirements using variable length array or c-style arrays resp and you should use them.
Note that,since C99 standard, VLA's are allowed in C.
Related
As we already know, VLA (standardized in C99) are not part of the standard in C++.
So the code below is "illegal" in C++:
void foo(int n) {
int vla[n];
for (int i = 0; i < n; ++i) {
vla[i] = i;
}
}
Despite of that the compiler (g++ and clang++) accepts the code as valid syntax, producing just a warning in case -pedantic flag is enable.
ISO C++ forbids variable length array ‘vla’ [-Wvla]
My questions are:
Why does the compiler accept that declaration?
The compiler cannot just reject an array in which length [is-no-know-at-compile-time]?
Is there a sort of compatibility syntax rule to follow?
What does the standard say about?
From the assembly code produced I see the compiler writes in the stack
in the loop, like a normal array, but I cannot find anything about the standard behaviour.
Why does the compiler accept that declaration?
Because its authors chose to make it do so.
GCC in particular allows, by default, a lot of non-standard stuff that was historically accepted by old C compilers. They like "compatibility" in that sense.
What does the standard say about [it]?
Precisely what the warning states it says about it: ISO C++ forbids variable length arrays.
C++ does not have VLAs.
Where you see one being accepted, it is a compiler extension; to find out how that compiler implements such an extension, you would have to ask the compiler's authors (or examine its source, if applicable).
The standard requires that a conforming compiler must "issue a diagnostic" when it encounters something that is illegal. Having done that, it's free to continue to compile the code with an implementation-specific meaning. (Note that "with an implementation-specific meaning" is a polite form of "with undefined behavior").
As we already know, VLA (standardized in C99) are not part of the standard in C++.
So the code below is "illegal" in C++:
void foo(int n) {
int vla[n];
for (int i = 0; i < n; ++i) {
vla[i] = i;
}
}
Despite of that the compiler (g++ and clang++) accepts the code as valid syntax, producing just a warning in case -pedantic flag is enable.
ISO C++ forbids variable length array ‘vla’ [-Wvla]
My questions are:
Why does the compiler accept that declaration?
The compiler cannot just reject an array in which length [is-no-know-at-compile-time]?
Is there a sort of compatibility syntax rule to follow?
What does the standard say about?
From the assembly code produced I see the compiler writes in the stack
in the loop, like a normal array, but I cannot find anything about the standard behaviour.
Why does the compiler accept that declaration?
Because its authors chose to make it do so.
GCC in particular allows, by default, a lot of non-standard stuff that was historically accepted by old C compilers. They like "compatibility" in that sense.
What does the standard say about [it]?
Precisely what the warning states it says about it: ISO C++ forbids variable length arrays.
C++ does not have VLAs.
Where you see one being accepted, it is a compiler extension; to find out how that compiler implements such an extension, you would have to ask the compiler's authors (or examine its source, if applicable).
The standard requires that a conforming compiler must "issue a diagnostic" when it encounters something that is illegal. Having done that, it's free to continue to compile the code with an implementation-specific meaning. (Note that "with an implementation-specific meaning" is a polite form of "with undefined behavior").
C has a really cool feature called variable length arrays. Its available in C90 and above, and it allows deferring the size of the array until runtime. See GCC's manual 6.19 Arrays of Variable Length.
I'm working in C++. At std=c++11, I'm catching a compile failure due to the use of alloca under Cygwin. I want to switch to variable length arrays, if possible. I also want to try and avoid std::vector and std::array because I want to stay out of the memory manager. I believe every little bit helps, so I'm happy to take these opportunities (that some folks consider peepholes).
Can I use a variable length array in C++03 and C++11?
VLAs are not in standard C++03 or C++11, so you'll better avoid them if you want to write strictly standard conforming code (and use e.g. std::vector, which generally use heap for its data - but you might use your own allocator...).
However, several C++ compilers (recent GCC & Clang) are accepting VLAs as an extension.
It is the same for flexible array members; they are not standard in C++ (only in C) but some compilers accept them.
dynarray-s did not get into the C++11 standard...
Not if you want code that is standard C++.
No C++ standard supports VLAs, but some C++ compilers do as a vendor-specific extension.
You can achieve a similar effect in C++ using the standard vector. Note that, unlike VLAs which can only be sized when created, a standard vector can be resized as needed (subject to performing appropriate operations on it).
hello every one i want to ask that i have read that we can declare dynamic array only by using pointer and using malloc or newlike
int * array = new int[strlen(argv[2])];
but i have wrote
int array[strlen(argv[2])];
it gave me no error
i have read that static array can only be declared by giving constant array size but here i have given a variable size to static array
why is it so thanks
is it safe to use or is there chance that at any latter stages it will make problem i am using gcc linux
What you have is called a variable-length array (VLA), and it is not part of C++, although it is part of C99. Many compilers offer this feature as an extension.
Even the very new C++11 doesn't include VLAs, as the entire concept doesn't fit well into the advanced type system of C++11 (e.g. what is decltype(array)?), and C++ offers out-of-the box library solutions for runtime-sized arrays that are much more powerful (like std::vector).
In GCC, compiling with -std=c++98/c++03/c++0x and -pedantic will give you a warning.
C99 support variable length array, it defines at c99, section 6.7.5.2.
What you have written works in C99. It is a new addition named "variable length arrays". The use of these arrays is often discouraged because there is no interface through which the allocation can fail (malloc can return NULL, but if a VLA cannot be allocated, the program will segfault or worse, behave erratically).
int array[strlen(argv[2])];
It is certainly not valid C++ Standard code, as it is defining a variable length array (VLA) which is not allowed in any version of C++ ISO Standard. It is valid only in C99. And in a non-standard versions of C or C++ implementation. GCC provides VLA as an extension, in C++ as well.
So you're left with first option. But don't worry, you don't even need that, as you have even better option. Use std::vector<int>:
std::vector<int> array(strlen(argv[2]));
Use it.
Some compilers aren't fully C++ standard compliant. What you pointed out is possible in MinGW (iirc), but it's not possible in most other compilers (like Visual C++).
What actually happens behind the scenes is, the compiler changes your code to use dynamically allocated arrays.
I would advice against using this kind of non-standard conveniences.
It is not safe. The stack is limited in size, and allocating from it based on user-input like this has the potential to overflow the stack.
For C++, use std::vector<>.
Others have answered why it "works".
I want to define a 2D array statically. The size of the array is determined by a variable.
How do I do this? I do not want to dynamically define the array. I heard that there is a way to do this.
Answer is No You Cannot in C++.
Dimensions of the array must be known at compile time.
int my_array[6][7]; // okay
int my_array[H][7]; // ISO C++ forbids variable length array
int my_array[6][W]; // ISO C++ forbids variable length array
int my_array[H][W]; // ISO C++ forbids variable length array
Some compilers do support Variable Length Arrays(VLA) through their own extension but VLA are not defined in the C++ standard, hence using VLA will be non conforming to C++ standard.
VLA's were introduced in C99 C standard. C++ was branched out from C standard of C98. By the time C introduced VLA, C++ already had Vectors and had no need to support or encourage VLA. Hence, VLA was never formally accepted in the C++ Standard, some C++ compiler still support VLA through compiler extensions.
Since, you tagged your Q C as well as C++, to summarize the answer:
In C99 & versions after that : You Can
Versions before C99: You Can't
In C++(Any version): You can(through compiler extensions) but You should'nt
Here is the legendary C++ FAQ which explains everything about arrays.
I learned a lot from it. :)
If one of the dimensions of the array is variable, then the size must be variable, then it must be dynamically sized - or sized in such a way that the the array is statically sized larger than the largest value that the variable could be.
I dont think so you can statically define it! However you can use vector but underneath it too does dynamic allocation for you
By "variable", I assume you're talking about a non-constant value.
In C99, yes:
int size = ...;
int array[size][size];
In C++, you can't. The alternative is to use pointers and dynamic allocation (or better yet, vectors).
In C versions prior to C99, it's also impossible. Use malloc().
This depends where and when the variable is initialized. If its something done at compile time you can use templates to get it done: template </* args */> struct ConstExpr{enum{value = /* math goes here */};};, else its impossible without selfmodifying code(and I'm pretty sure this is gonna very dangerous, because you'll need to alter the PE so you can somehow get your allocated space change before its virtualized).