Почему мы используем статические с массивом указателей? - PullRequest
2 голосов
/ 17 апреля 2010

Почему мы используем статические с массивом указателей? Какова связь между статическим и массивом указателей?

Например:

int main()
{
  int a[]={1,2,3};
  int *p[]={a,a+1,a+2}; 
  ......
  return 0;
}

Этот код показывает неправильную инициализацию - почему? Тогда как работает следующий код:

int main()
{
   static int a[]={1,2,3};
   static int *p[]={a,a+1,a+2}; 
   ...
   return 0;
}

Ответы [ 2 ]

8 голосов
/ 17 апреля 2010

В C89 (исходное «ANSI C») значения, используемые в списках инициализаторов, должны быть «постоянными выражениями». Один тип константного выражения является адресной константой, а указатель на объект со статической продолжительностью хранения является адресной константой.

Однако указатель на объект с автоматической продолжительностью хранения равен , а не адресной константе (ее значение неизвестно во время компиляции), поэтому его нельзя использовать в списке инициализатора.

Вам нужно только, чтобы массив a имел статическую продолжительность хранения - тоже будет работать следующее:

main()
{
  static int a[]={1,2,3};
  int *p[]={a,a+1,a+2}; 
  ......
}

C99 ослабил это ограничение для инициализаторов для объектов, у которых есть автоматическая продолжительность хранения (именно поэтому gcc с этим согласен).


Почему это так? Списки инициализаторов обычно используются для инициализации потенциально больших объектов, таких как массивы или структуры. Объекты с автоматическим хранением должны инициализироваться заново каждый раз, когда вводится функция, и правила C89 позволяют операциям записи компилятора выполнять эту инициализацию, испуская простой вызов memcpy() (используя в качестве источника статический «шаблон», который соответствует инициализатору список). Согласно правилам C99, компилятор потенциально должен выдавать произвольно сложный блок кода инициализации.

0 голосов
/ 17 апреля 2010

С Visual C код работает. Тем не менее, он генерирует предупреждение уровня 4 C4204 , означающее, что они считают, что это специфическое для Microsoft расширение стандарта C. Как сказали caf и AndreyT, это не является частью стандарта C, разрешающего это.

РЕДАКТИРОВАТЬ: Со стандартом C я имею в виду C89.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...