Переменно модифицированный массив в области видимости файла в C

У меня есть такой код:

static int a = 6;
static int b = 3;

static int Hello[a][b] =
{
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3}
};

но когда я его компилирую, он говорит об ошибке:

переменно измененный "Hello" в области видимости файла

Как такое могло произойти? и как я мог это исправить?

5 ответов

Решение

Вы не можете иметь статический массив, размер которого указан как переменная

Вот почему константы должны быть #defineд:

#define a 6

Таким образом препроцессор заменит a с 6, сделав это действительным заявлением.

Простой ответ variable modified array at file scope is not possible,

Подробно:

сделать время компиляции integral constant expression, поскольку длина массива должна быть указана во время компиляции.

как это:

#define a 6
#define b 3

Или следуйте стандарту C99. и скомпилировать как для gcc.

gcc -Wall -std=c99 test.c -o test.out

Проблема здесь в том, что массив переменной длины с предоставлением длины может не инициализироваться, поэтому вы получаете эту ошибку.

просто

static int a =6;
static int b =3;

void any_func()
{
int Hello [a][b]; // no need of initialization no static array means no file scope.
}

Теперь используйте для цикла или любого цикла, чтобы заполнить массив.

Для получения дополнительной информации просто ДЕМО:

#include <stdio.h>
static int a = 6; 
int main()
{
int Hello[a]={1,2,3,4,5,6}; // see here initialization of array Hello it's in function
                            //scope but still error
return 0;
}


root@Omkant:~/c# clang -std=c99 vararr.c -o vararr
vararr.c:8:11: error: variable-sized object may not be initialized
int Hello[a]={1,2,3,4,5,6};
          ^
1 error generated. 

Если вы удалите статический файл и обеспечите инициализацию, он выдаст ошибку, как описано выше

Но если вы сохраните статичность и инициализацию, все равно будет ошибка.

Но если вы удалите инициализацию и сохраните static ниже ошибка придет.

error: variable length array declaration not allowed at file scope
static int Hello[a];
           ^     ~
1 error generated.

Поэтому объявление массива переменной длины недопустимо в области видимости файла, поэтому сделайте его функцией или областью видимости блока внутри любой функции (но не забывайте, что при создании области видимости функции необходимо удалить инициализацию)

ПРИМЕЧАНИЕ: так как это C помечены так, делая a а также b как const не поможет тебе, но в C++const будет работать нормально.

При использовании CLANG/LLVM работает следующее:

static const int a = 6;
static const int b = 3;

static int Hello[a][b] =
{
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3},
    { 1,2,3}
}; 

(Чтобы увидеть его в сгенерированной сборке, нужно использовать Hello, чтобы он не был оптимизирован)

Тем не менее, это вызовет ошибку, если выбран режим C99 (-std=c99), и только предупреждение (Wgnu-fold-constant) будет выбрано, если выбран -pedantic.

GCC, похоже, не позволяет этого (const интерпретируется как доступный только для чтения)

Смотрите объяснение в этой теме:

Ошибка "Элемент инициализатора не является постоянной" без причины в Linux GCC, компиляция C

Да, это досадно:

const int len = 10;

int stuff[len];

Выдает ошибку. Я стараюсь избегать использования #define x, потому что const int - лучший способ объявления константы, но тогда у вас есть такие случаи, когда const int не является истинной константой, даже если компилятор хорошо знает, что это так.

Размеры массива должны быть постоянными выражениями, и ваш друг «компилятор» должен быть проинформирован об этом. Итак, сообщите компилятору, что a и b являются постоянными значениями.

      static constexpr int a = 6;

static constexpr int b = 3;

static int Hello[a][b] = { { 1,2,3 }, { 1,2,3 }, { 1,2,3 }, { 1,2,3 }, { 1,2,3 }, { 1,2,3 } };
Другие вопросы по тегам