Reputation: 929
Why is it that when I define an array of floats
like :
const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // Illegal
outside any function (i.e in global), it is illegal to do so. while if I do the same thing inside any function (including main() ) like:
void f() {
const int i[] = { 1, 2, 3, 4 };
float f[i[3]];
cout << sizeof(f);
}
main()
{
f();
}
then everything works fine and it outputs the size as 16 successfully. why is this difference ? Is it because of the change in the storage location from static (initially) to the stack ?
(PS: I know that in C++ an array can not be defined using a variable whose value is not known at the compile time, BUT still, then how is it working in the function ? )
Upvotes: 1
Views: 212
Reputation: 111130
By default, if you don't specify strict standard compliance, compilers often allow C features to be used in C++ (and vice versa). Both GCC and Clang allow such a C99 feature, namely VLAs, to be used by default. (Visual Studio, OTOH, does not support VLAs even in C mode.) Note, however, that VLAs can be defined only in block scope.
6.7.6.2 Array declarators
2 If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.
So, a global VLA does not work in C++ (with lax compiler settings) whereas a function local VLA does.
Try compiling the following
$ cat float.cpp
int main() {
int i = 2;
const float f[i] = { 1, 2 };
}
with g++ -std=c++98 -Wall -ansi -pedantic float.cpp
and you'd get something like:
float.cpp: In function 'int main()':
float.cpp:3:18: warning: ISO C++ forbids variable length array 'f' [-Wvla]
float.cpp:3:29: error: variable-sized object 'f' may not be initialized
float.cpp:3:15: warning: unused variable 'f' [-Wunused-variable]
Upvotes: 3
Reputation: 6357
C++11 allow this :
#include <iostream>
constexpr int i[] = {1,2,3,4};
float k[i[2]];
int main()
{
std::cout << sizeof(k) << "\n";
}
and it'll be well formed.
As for the initial question, this is probably a G++ extension.
Upvotes: 2