When you declare an array with a length specifier, only constants are allowed.
Actually it's when the program is compiled that the array length is evaluated.
Note however that it's illegal in C++ to declare int test[];
like the compiler has no way to know how much space to allocate for the variable.
Without a length specifier, there is no actual memory that is reserved for the array, and you have to resort to using pointers and dynamic memory allocation:
int * test = new int[12];
// or
int * test = new int[val]; // variable works here
// and don't forget to free it
delete [] test;
Using int test[12]
actually creates an array that is statically initialized once and for all to contain 12 integers at compile time.
Do not ever attempt to do delete [] test
with a variable declared this way, as it's most certainly going to make your program crash.
To be precise, if the array is declared in a function, it will use space on the program stack, and if declared in a global context, program data memory will be used.