Инициализировать размер массива в C на уровне файла

Я хотел бы инициализировать массив на основе вычислений, но компилятор выдает мне ошибку, когда я пытаюсь это сделать (я использую GCC версии 6.3.0):

const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
char textgrid[SCREEN_HEIGHT/16][SCREEN_WIDTH/16];

Ошибка компилятора выглядит следующим образом:

error: variably modified 'textgrid' at file scope

Есть ли способ сделать это на уровне файла?

Кажется, я не могу использовать вычисления как часть оператора #define, чтобы выполнить это, потому что следующее дает мне ту же ошибку:

#define TEXTGRID_WIDTH (SCREEN_WIDTH / 16)
#define TEXTGRID_HEIGHT (SCREEN_HEIGHT / 16)
char textgrid[TEXTGRID_HEIGHT][TEXTGRID_WIDTH];

3 ответа

Согласно стандарту C (6.7.6.2 Массив объявлений)

  1. ... Если размер является целочисленным константным выражением и тип элемента имеет известный постоянный размер, тип массива не является типом массива переменной длины; в противном случае тип массива является типом массива переменной длины.

и (6.7.6.2 Массив объявлений)

2 Если идентификатор объявлен как имеющий переменно измененный тип, он должен быть обычным идентификатором (как определено в 6.2.3), не иметь никакой связи и иметь либо область действия блока, либо область действия прототипа функции. Если идентификатор объявлен как объект со статическим или потоковым сроком хранения, он не должен иметь тип массива переменной длины.

и наконец ( 6.6 постоянных выражений)

6 Целочисленная константа-выражение117) должна иметь целочисленный тип и иметь только те операнды, которые являются целочисленными константами, константами перечисления, символьными константами, выражениями sizeof, результатом которых являются целочисленные константы, и плавающими константами, которые являются непосредственными операндами приведений. Операторы приведения в выражении с целочисленной константой должны преобразовывать только арифметические типы в целочисленные типы, кроме как в качестве части операнда к оператору sizeof.

Таким образом, вы можете использовать любые определенные именованные константы, такие как

#define SCREEN_WIDTH  800
#define SCREEN_HEIGHT 600

или счетчики

enum { SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600 };

Когда ты пишешь const int SCREEN_WIDTH = 800Вы определяете объект с именем SCREEN_WIDTH который содержит значение 800.

Так как SCREEN_WIDTH это объект, а не значение, вы не можете использовать его для значения в константном выражении. Хотя его значение для нас не меняется и не очевидно, оно не может считаться константой времени компиляции.

Чтобы определить массив в области видимости файла, вы должны использовать измерения, которые являются константными выражениями (выражениями, сформированными полностью из констант времени компиляции).

В С const квалифицированная переменная не считается постоянной времени компиляции. Вам понадобится постоянная времени компиляции, чтобы упомянуть размер массива в области видимости файла.

Вы можете использовать #define заявления для этой цели.

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