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.

3
  • 9
    your second case is illegal too. Note that it works and legal are too different things! Commented Sep 25, 2013 at 13:50
  • 2
    @Walter two different things, even... Commented Sep 25, 2013 at 14:01
  • 1
    @twalberg could be interpreted as "the difference between them is too big to ignore" Commented Sep 25, 2013 at 17:24

4 Answers 4

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
Sign up to request clarification or add additional context in comments.

1 Comment

Can you through some light on compile-time known bound please..Thanks.
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]; 

3 Comments

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.
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.
It would depend on the usage (in this case, it would still be const). See stackoverflow.com/questions/4748083/… and stackoverflow.com/questions/13346879/… for the difference between const and constexpr
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).

2 Comments

the 1st should be constexpr int SIZE = 3;, no?
@BЈовић 3 is not an expression: stackoverflow.com/questions/4748083/…
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?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.