9

I am new to C++.I was going through a C++ book and it says

const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // Illegal

It says the declaration of the float variable is invalid during compilation.Why is that?

Suppose if we use

int i = 3;
float f[i];

It works.

What is the problem with the first situation?

Thanks.

starkk92
  • 5,754
  • 9
  • 43
  • 59

4 Answers4

15

So the first is illegal because an array must have a compile-time known bound, and i[3], while strictly speaking known at compile time, does not fulfill the criteria the language sets for "compile-time known".

The second is also illegal for the same reason.

Both cases, however, will generally be accepted by GCC because it supports C99-style runtime-sized arrays as an extension in C++. Pass the -pedantic flag to GCC to make it complain.

Edit: The C++ standard term is "integral constant expression", and things qualifying as such are described in detail in section 5.19 of the standard. The exact rules are non-trivial and C++11 has a much wider range of things that qualify due to constexpr, but in C++98, the list of legal things is, roughly:

  • integer literals
  • simple expressions involving only constants
  • non-type template parameters of integral type
  • variables of integral type declared as const and initialized with a constant expression
Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
3

Your second example doesn't work and it shouldn't work. i must be constant. This works

const int i = 3;
float f[i];
wl2776
  • 4,099
  • 4
  • 35
  • 77
  • 1
    It will *work* (that is, both compile and perform as expected) on some compilers (e.g. gcc) if certain flags are not set (e.g. -pedantic). That does not mean it is legal according to the standard, however. – Zac Howland Sep 25 '13 at 14:05
  • Ok, I've got it. `const int const i[4] = {1, 2, 3, 4};` doesn't work also, at least in Visual Studio 2010. As I understand, it would be `constexpr` in C++11. – wl2776 Sep 25 '13 at 14:11
  • It would depend on the usage (in this case, it would still be `const`). See http://stackoverflow.com/questions/4748083/when-should-you-use-constexpr-capability-in-c11 and http://stackoverflow.com/questions/13346879/const-vs-constexpr-on-variables for the difference between `const` and `constexpr` – Zac Howland Sep 25 '13 at 14:16
2

Just to expound on Sebastian's answer:

When you create a static array, the compiler must know how much space it needs to reserve. That means the array size must be known at compile-time. In other words, it must be a literal or a constant:

const int SIZE = 3;
int arr[SIZE]; // ok

int arr[3]; // also ok

int size = 3;
int arr[size]; // Not OK

Since the value of size could be different by the time the array is created, the oompiler won't know how much space to reserve for the array. If you declare it as const, it knows the value will not change, and can reserve the proper amount of space.

If you need an array of a variable size, you will need to create it dynamically using new (and make sure to clean it up with delete when you are done with it).

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
0

For arrays with lengths known only at runtime in C++ we have std::vector<T>. For builtin arrays the size must be known at compile-time. This is also true for C++11, although the much older C99-standard already supports dynamic stack arrays. See also the accepted answer of Why doesn't C++ support dynamic arrays on the stack?

Community
  • 1
  • 1
Andreas Spindler
  • 7,568
  • 4
  • 43
  • 34