Я добираюсь, ошибка на строке 6 (инициализируйте my_foo к foo_init) следующей программы, и я не уверен, что понимаю почему.
typedef struct foo_t {
int a, b, c;
} foo_t;
const foo_t foo_init = { 1, 2, 3 };
foo_t my_foo = foo_init;
int main()
{
return 0;
}
Следует иметь в виду, что это - упрощенная версия большего, многофайлового проекта, я продолжаю работать. Цель состояла в том, чтобы иметь единственную константу в объектном файле, который несколько файлов могли использовать для инициализации структуры состояния. Так как это - встроенная цель с ограниченными ресурсами, и структура не является настолько маленькой, я не хочу несколько копий источника. Я предпочел бы не использовать:
#define foo_init { 1, 2, 3 }
Я также пытаюсь написать портативный код, таким образом, мне нужно решение, это - допустимый C89 или C99.
Это имеет отношение к ORGs в объектном файле? Это инициализировало переменные, входят в один ORG и инициализируются путем копирования содержания второго ORG?
Возможно, я должен буду просто изменить свою тактику и иметь функцию инициализации, делают все копии при запуске. Если нет другие идеи там?
В языке Си объекты со статической длительностью хранения должны инициализироваться постоянными выражениями или агрегатными инициализаторами, содержащими постоянные выражения.
"Большой" объект никогда не является константным выражением в языке Си, даже если объект объявлен как const
.
Более того, в языке Си термин "константа" относится к литеральным константам (таким как 1
, 'a'
, 0xFF
и так далее), членам перечисления и результатам таких операторов, как sizeof
. Const-qualified объекты (любого типа) не являются константами в терминологии языка Си. Их нельзя использовать в инициализаторах объектов со статической длительностью хранения, независимо от их типа.
Например, это НЕ константа
const int N = 5; /* `N` is not a constant in C */
Приведенное выше N
было бы константой в C++, но не является константой в C. Поэтому, если вы попытаетесь выполнить
static int j = N; /* ERROR */
вы получите ту же ошибку: попытка инициализации статического объекта неконстантой.
Именно по этой причине в языке Си мы преимущественно используем #define
для объявления именованных констант, а также прибегаем к #define
для создания именованных агрегатных инициализаторов.
Это ограничение языка. В разделе 6.7.8/4:
Все выражения в инициализаторе для объекта, который имеет статическую длительность хранения, должны быть константными выражениями или строковыми литералами.
В разделе 6.6 спецификация определяет, что должно считаться константным выражением. Нигде не сказано, что переменная const должна считаться константным выражением. Компилятор может расширить это определение (6.6/10 - Реализация может принимать другие формы константных выражений
), но это ограничит переносимость.
Если вы можете изменить my_foo
так, чтобы он не имел статического хранилища, вы будете в порядке:
int main()
{
foo_t my_foo = foo_init;
return 0;
}