In C89 (the original "ANSI C"), values used in initialiser lists must be "constant expressions". One type of constant expression is an address constant, and a pointer to an object with static storage duration is an address constant.
However, a pointer to an object with automatic storage duration is not an address constant (its value is not known at compile-time), so it cannot be used in an initialiser list.
You only need to make the array a
have static storage duration - the following will work too:
main()
{
static int a[]={1,2,3};
int *p[]={a,a+1,a+2};
......
}
C99 has relaxed this restriction for initialisers for objects that have automatic storage duration (which is why gcc is OK with it).
Why is it so? Initialiser lists are typically used for initialising potentially large objects, like arrays or structures. Objects with automatic storage duration must be initialised anew each time the function is entered, and the C89 rules allow compiler writes to do this initialisation by emitting a simple memcpy()
call (using as source a static "template", which corresponds to the initialiser list). Under the C99 rules, the compiler potentially has to emit an arbitrarily complicated block of initialisation code.