Изменяемый массив в области видимости файла
Я хочу создать постоянный статический массив, который будет использоваться в моем файле реализации 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 цели:
- Иметь массив, который доступен по всему файлу
- Инкапсулировать
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 };
Также возможно использование перечисления.
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, когда это возможно, так как статический констант безопасен по типу.