Я хочу создать постоянный статический массив, который будет использоваться во всем моем файле реализации 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
в переменную, чтобы у меня не было одного и того же литерала, разбросанного в разных местах в моем файле
Какие-либо предложения?
[EDIT] Нашел это в C Faq: http://c-faq.com/ansi/constasconst.html
#define kNUM_TYPES 4
?@"An NSString literal"
). Единственное, что не так с вашим фрагментом кода, это то, что нет необходимости в точке с запятой.Ответы:
Причина этого предупреждения в том, что const в c не означает константу. Это означает «только чтение». Таким образом, значение хранится по адресу памяти и потенциально может быть изменено машинным кодом.
источник
const
(например, отведениеconst
от указателя и сохранение значения) является неопределенным поведением; следовательно, значение такого объекта является константой времени компиляции или времени выполнения (в зависимости от продолжительности хранения). Значение нельзя использовать в постоянном выражении просто потому, что стандарт C не говорит, что это может быть. (Отбрасываниеconst
и сохранение значения разрешены, если целевой объект определен безconst
выделения или динамически выделен; строковые литералы неconst
могут быть записаны в них.)extern
в разных TU могут быть константы, значение которых не известно при компиляции текущего TU.Если вы все равно собираетесь использовать препроцессор, в соответствии с другими ответами, вы можете заставить компилятор определять значение
NUM_TYPES
автоматически:#define NUM_TYPES (sizeof types / sizeof types[0]) static int types[] = { 1, 2, 3, 4 };
источник
sizeof
объектов является константой времени компиляции.#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 };
источник
Имхо, это недостаток многих компиляторов c. Я точно знаю, что компиляторы, с которыми я работал, не хранят переменную "static const" по адресу, а заменяют использование в коде самой константой. Это можно проверить, поскольку вы получите одинаковую контрольную сумму для созданного кода при использовании директивы препроцессоров #define и при использовании статической переменной const.
В любом случае вы должны использовать статические константные переменные вместо #defines, когда это возможно, поскольку статическая константа безопасна по типу.
источник
static const
переменной. Описываемое вами поведение может быть допустимой оптимизацией, но, конечно, не всегда может работать.