Переменно модифицированный массив в области видимости файла в 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 } };