Referring to const value at compile time - when is a const's definition really available?
I tried
const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // g++ cries "error: array bound is not an integer constant"
int main()
{
const int j[] = { 0, 1, 2, 3 };
float g[j[3]]; // compiler is happy :)
return 0;
}
What is the difference between the two aggregates? How come referring to a const aggregate's element inside main() is val开发者_Python百科id when it's invalid at the global scope?
In C++ sizes in array declaration have to be Integral Constant Expressions (ICE). By definition, ICE in C++ cannot include a value taken from an array, regardless of whether it is a const
array or not. So, in both cases i[3]
and j[3]
are not ICEs and cannot be used as sizes in array declarations. For this reason both declarations - f
and g
- are illegal in C++.
However, since you are using GCC, in the second case a non-standard compiler extension comes into play. When you are declaring an automatic array, GCC allows you to specify a non-constant size (i.e. run-time size) for the array (this is basically C99's VLAs carried over to C++). This is why it is "happy", even though the code is not legal in C++. Compile in -ansi -pedantic-error
mode and you should get a diagnostic message (an error) for each declaration.
Compiler can use those constants as compile-time constants, which it can keep in its symbol table. But virtually,no compiler is sophisticated enough to store an aggregate in its symbol table, so the value can't be used at compile time.
Furthermore non-standard gcc extensions allow you to use variable length automatic arrays.
Thats's why not only this:
const int j[] = { 0, 1, 2, 3 };
float g[j[3]];
but also this is allowed by the compiler:
int j[] = { 0, 1, 2, 3 };
float g[j[3]];
GCC 3.4.5 says "variable-size type declared outside of any function" and 4.4.0 says "array bound is not an integer constant" for f[i[3]]
, which leads me to believe that neither i[3]
nor j[3]
is constant, though I couldn't tell you why. If I had to take a wild guess I'd say perhaps it has something to do with the addresses of i
and j
not being known until link time, but I'm really not sure.
Edit: I got beaten to it. Leaving behind my inferior answer for posterity.
精彩评论