В C89 (исходное «ANSI C») значения, используемые в списках инициализаторов, должны быть «постоянными выражениями». Один тип константного выражения является адресной константой, а указатель на объект со статической продолжительностью хранения является адресной константой.
Однако указатель на объект с автоматической продолжительностью хранения равен , а не адресной константе (ее значение неизвестно во время компиляции), поэтому его нельзя использовать в списке инициализатора.
Вам нужно только, чтобы массив a
имел статическую продолжительность хранения - тоже будет работать следующее:
main()
{
static int a[]={1,2,3};
int *p[]={a,a+1,a+2};
......
}
C99 ослабил это ограничение для инициализаторов для объектов, у которых есть автоматическая продолжительность хранения (именно поэтому gcc с этим согласен).
Почему это так? Списки инициализаторов обычно используются для инициализации потенциально больших объектов, таких как массивы или структуры. Объекты с автоматическим хранением должны инициализироваться заново каждый раз, когда вводится функция, и правила C89 позволяют операциям записи компилятора выполнять эту инициализацию, испуская простой вызов memcpy()
(используя в качестве источника статический «шаблон», который соответствует инициализатору список). Согласно правилам C99, компилятор потенциально должен выдавать произвольно сложный блок кода инициализации.