Variable Length Array (VLA) in C++ compilers - c++

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

Related

Why we need dynamically allocated array when we could do the same thing with regular arrays? [duplicate]

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

Is reading an integer and then declaring array of size correspond to that integer is dynamic allocation [duplicate]

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

Why can I create and use this array at runtime? [duplicate]

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++ array size declaration and const

I'm just jumping into C++, coming from C
In C (89/90), a const is not actually a constant (as opposed to a #define'd, enum, or literal), but rather read-only once set. I.e, I can:
const int x = rand();
and that's fine - the point being x isn't known until runtime. Hence, I can't
int arr[x]; // error - x is not a compile-time constant
Then, one of the C standards (99?) went ahead and allowed for variable-length arrays. Although I normally code against the ANSI standard in C, this has actually had an impact now that I am trying to pickup C++11.
As far as I know, C++ does not allow for variable-length arrays. However, many compilers allow it as an extension (GCC ?). The problem is, now that I am trying to learn C++11, I can't tell if what I'm coding is valid C++, or C++ extended with C99-compatibility. Ex:
std::default_random_engine e{};
std::uniform_int_distribution<int> d{};
const int x{d(e)};
int arr[x]; // compiles
I can't tell if this is valid C++ or not. Clearly, the value of x is not known until runtime. I think I may not understand the difference between C and C++ const?
You are correct VLAs are a C99 feature(optional in C11) and the C++ standard does not include this feature although both gcc and clang allow them in C++ as an extension. We can see they are not allowed by going to the draft C++11 standard section 8.3.4 Arrays which says:
D1 [ constant-expressionopt] attribute-specifier-seqopt
^^^^^^^^^^^^^^^^^^^^^^
For both gcc and clang using the -pedantic flag will warn when you are using an extension. If you are targeting C++11 then you should also specify that using -std=c++11. You can use -pedantic-errors to turn the warning into errors. If you compile your code using -pedantic you should see the the following warning:
warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[x]; // compiles
^
gcc documents their support for various standards, defaults and flags to enforce standard on their Language Standards Supported by GCC page and it says:
to obtain all the diagnostics required by the standard, you should
also specify -pedantic (or -pedantic-errors if you want them to be
errors rather than warnings).
In general clang supports what gcc does but you can find more details on their Language Compatibility page.
Note as mentioned by GingerPlusPlus std:vector is considered the alternative for VLA in C++.

Defining the size of array using variable

Is this valid in C language?
#include <stdio.h>
int main()
{
int i = 5;
int a[i]; // Compiler doesn't give error here. Why?
printf("%d",sizeof(a)); //prints 5 * 4 =20. 4 is the size of integer datatype.
return 0;
}
Compiler doesn't give error at the statement int a[i];. i isn't a constant then how can it compile successfully? Is it because I am using gcc compiler? Is it allowed in C++?
Yes, this is valid as of C99, and is called a variable-length array (VLA). In other words, it has been in an official language standard for around 14 years.
No, it's not valid in C++, see this question for details.
Also note that sizeof is not a function, so that can be written as printf("%zu\n", sizeof a); which also uses the proper format specifier for a size_t value.
This is valid C99 it is called Variable Length Array(VLA) gcc supports VLA as an extension outside of C99 mode with respect to C++ both gcc and clang support variable length arrays as an extension even though this is really a C99 feature.
You can build using the -pedantic argument in gcc and clang both will give a warning similar to the following:
warning: variable length arrays are a C99 feature [-Wvla-extension]
sizeof is expected to work correctly with VLA although it will be evaluated instead of an integer constant. Although you do have undefined behavior in your code since you specified the wrong format specifier for size_t which is zu and not d. The C99 draft standard in section 7.19.6.1 The fprintf function which printf's section refers back to for the format string paragraph 9 says:
If a conversion specification is invalid, the behavior is undefined.[...]
I'd just add to unwind's answer that in C++14, there will be runtime-sized arrays, which work pretty much the same as VLA.
See chapter 8.3.4 in N3690 (array of runtime bound of T)
They seem to be supported in clang-3.3 (in C++1y mode), but NOT in GCC 4.8 (the support should come in GCC 4.9).
When you write the code in pre-C++14 mode (c++03, c++11), your code will probably compile, but it should issue a warning about using a C99 feature not supported in C++.
And you always should compile with most pedantic warnings enabled :)
Sizeof operator is compiler independent.
You could read more about this in the following links ::
VLA-as-function-argument