Почему я получаю сообщение об ошибке, когда инициализатор не является константой?

Я использую следующий код.

const int X_ORIGIN = 1233086;             
const int Y_ORIGIN = -4728071;              
const int Z_ORIGIN = 4085704;
const int xyzOrigin[NUM_DIMENSIONS] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN};

Когда я его компилирую, GCC дает мне следующую ошибку.

Transformations.h: 16: 1: ошибка: элемент инициализации не является константой

Что это значит? Как я могу исправить свой код?

Ответ 1

Вы не можете сделать это в глобальной области действия на C, только в локальной области, то есть внутри функции:

#define NUM_DIMENSIONS 3

const int X_ORIGIN = 1233086;             
const int Y_ORIGIN = -4728071;              
const int Z_ORIGIN = 4085704;

const int xyzOrigin[NUM_DIMENSIONS] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN}; // FAIL

void foo(void)
{
    const int xyzOrigin[NUM_DIMENSIONS] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN}; // OK
}

В качестве альтернативы вы можете скомпилировать код как С++, а не C.

Ответ 2

Часто люди вводят в заблуждение путем именования ключевого слова const, подразумевая что-то постоянного значения, которое невозможно изменить. В C, по крайней мере, это означает readonly. const квалифицированные объекты в области файла не имеют правильной константы, чтобы служить в качестве инициализаторов массива.

В качестве примера для непостоянной константы, вполне нормально объявлять

 const volatile unsigned int milliseconds_since_boot;

является значением, которое обновляется вне контроля компилятора (думаю, регистр HW) и что вам не разрешено назначать его, то есть он доступен только для чтения.

Ответ 3

Я не лучший программист;) но я бы сделал это:

#define X_ORIGIN (1233086)
#define Y_ORIGIN (-4728071)
#define Z_ORIGIN (4085704)
const int xyzOrigin[NUM_DIMENSIONS] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN};

Таким образом, это просто текстовая подстановка. Если компилятор все еще плюет на манекен, по крайней мере, вы на шаг ближе к пониманию, где проблема.

Ответ 4

В качестве альтернативы это также будет работать в этом случае:

enum { X_ORIGIN = 1233086,
       Y_ORIGIN = -4728071,
       Z_ORIGIN = 4085704 };

const int xyzOrigin[] = { X_ORIGIN, Y_ORIGIN, Z_ORIGIN };

int main()
{
    return 0;
}

Ответ 5

В языках C объекты со статической продолжительностью хранения должны быть инициализированы с помощью константных выражений или с агрегатными инициализаторами, содержащими постоянные выражения. - Ответ AndreyT

После прочтения вы должны знать, что NUM_DIMENSIONS, если он имеет const -qualification, не является константой! Тогда вы не можете инициализировать свой массив таким образом.

Для использования этого кода:

const int xyzOrigin[NUM_DIMENSIONS] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN};

Вы должны использовать: #define NUM_DIMENSIONS 3, или вы можете просто объявить без какой-либо переменной внутри квадратных скобок const int xyzOrigin[] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN};

Ответ 6

Как сказал триклозан:

main()
{
    const int X_ORIGIN = 1233086;
    const int Y_ORIGIN = -4728071;
    const int Z_ORIGIN = 4085704;
    const int xyzOrigin[] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN};
}

это прекрасно работает...

или, если вы знаете размеры заранее, это:

#define DIM 3

main()
{
    const int X_ORIGIN = 1233086;
    const int Y_ORIGIN = -4728071;
    const int Z_ORIGIN = 4085704;
    const int xyzOrigin[DIM] = {X_ORIGIN, Y_ORIGIN, Z_ORIGIN};
}