Изменяемый массив в области видимости файла

Я хочу создать постоянный статический массив, который будет использоваться в моем файле реализации Objective C, похожий на что-то вроде этого на верхнем уровне моего ".m" файла:

static const int NUM_TYPES = 4;
static int types[NUM_TYPES] = { 
  1,
  2, 
  3, 
  4 };

Я планирую использовать NUM_TYPES позже в файле, поэтому я хотел поместить его в переменную.

Однако, когда я делаю это, я получаю ошибку

"Изменяемые типы в области файла"

Я понимаю, что это может быть как-то связано с размером массива как переменной (я не получаю это сообщение, когда помещаю туда целочисленный литерал, например static int types[4]).

Я хочу это исправить, но, возможно, я все делаю неправильно... У меня есть 2 цели:

  1. Иметь массив, который доступен по всему файлу
  2. Инкапсулировать NUM_TYPES в переменную, поэтому у меня нет одного и того же литерала разбросаны по разным местам в моем файле

Какие-либо предложения?

[РЕДАКТИРОВАТЬ] Нашел это в C Faq: http://c-faq.com/ansi/constasconst.html

6 ответов

Причина этого предупреждения в том, что const в c не означает постоянную. Это означает "только для чтения". Таким образом, значение хранится по адресу памяти и может быть изменено машинным кодом.

Если вы все равно собираетесь использовать препроцессор, как и в других ответах, то вы можете заставить компилятор определять значение NUM_TYPES автомагически:

#define NUM_TYPES (sizeof types / sizeof types[0])
static int types[] = { 
  1,
  2, 
  3, 
  4 };
#define NUM_TYPES 4

Также возможно использование перечисления.

typedef enum {
    typeNo1 = 1,
    typeNo2,
    typeNo3,
    typeNo4,
    NumOfTypes = typeNo4
}  TypeOfSomething;

Как уже объяснялось в других ответах, const в C просто означает, что переменная только для чтения. Это все еще значение времени выполнения. Тем не менее, вы можете использовать enum как реальная константа в C:

enum { NUM_TYPES = 4 };
static int types[NUM_TYPES] = { 
  1, 2, 3, 4
};

Imho, это недостаток во многих c компиляторах. Я точно знаю, что компиляторы, с которыми я работал, не хранят переменную "static const" по адресу, а заменяют использование в коде самой константой. Это можно проверить, так как вы получите ту же контрольную сумму для созданного кода при использовании директивы препроцессора #define и при использовании статической переменной const.

В любом случае вы должны использовать статические константные переменные вместо #defines, когда это возможно, так как статический констант безопасен по типу.

Другие вопросы по тегам