Инициализация глобальной структуры в C

Что лучший способ состоит в том, чтобы выполнить следующее в C?

#include <stdio.h>

struct A
{
    int x;
};

struct A createA(int x)
{
    struct A a;
    a.x = x;
    return a;
}

struct A a = createA(42);

int main(int argc, char** argv)
{
    printf("%d\n", a.x);
    return 0;
}

Когда я пытаюсь скомпилировать вышеупомянутый код, компилятор сообщает о следующей ошибке:

"элемент инициализатора не является постоянным"

Плохая строка - этот:

struct A a = createA(42);

Кто-то может объяснить что не так? Я не очень опытен в C.Спасибо!

16
задан N 1.1 26 March 2010 в 08:42
поделиться

5 ответов

Почему бы не использовать статическую инициализацию?

struct A a = { 42 };
14
ответ дан 30 November 2019 в 16:18
поделиться

Вы не можете вызывать функции при такой статической инициализации. В вашем примере вы можете просто использовать:

struct A a = {42};

Если у вас более сложная установка, вам нужно будет предоставить функцию создания библиотеки и уничтожения библиотеки, которую вы заставляете вызывать пользователей вашей библиотеки (при условии, что вы хотите быть переносимым), или вам придется использовать C ++ и воспользоваться конструкторами / деструкторами, или вам придется воспользоваться нестандартным и непереносимым __attribute __ ((constructor)), чтобы создать функцию, которая запускается при запуске для ее инициализации.

Если у вас более сложная настройка, я настоятельно рекомендую вам использовать C ++:

class A
{
   A(){
      // can do initialization in the constructor
   }
   // ...
};

A a;

Однако, если вам нужно придерживаться чистого C, переносимая вещь, которую нужно сделать, - это использовать что-то вроде:

typedef void* mylibrary_attr_t;
typedef void* mylibrary_t;

#ifdef __cplusplus
#   define EXTERNC extern "C"
#else
#   define EXTERNC
#endif

EXTERNC int mylibrary_attr_init(mylibrary_attr_t*);
EXTERNC int mylibrary_attr_setparam1(mylibrary_attr_t,int);
EXTERNC int mylibrary_attr_setparam2(mylibrary_attr_t,double);
// .. more functions for various attributes used by library
EXTERNC void mylibrary_attr_destroy(mylibrary_attr_t*);

EXTERNC int mylibrary_init(mylibrary_t*,mylibrary_attr_t);
EXTERNC void mylibrary_destroy(mylibrary_t*);

// functions that use mylibrary_t
// ...

В основном, в выше, вы должны инициализировать свою библиотеку с помощью mylibrary_init и удалить свою библиотеку с помощью mylibrary_destroy . Для функций, использующих вашу библиотеку, потребуется инициализированный экземпляр mylibrary_t , поэтому человек, создавший основную функцию, будет нести ответственность за вызов mylibrary_init . Также хорошо сделать функцию инициализации зависимой от параметра «атрибуты», который по умолчанию можно заменить на 0 или NULL. Таким образом, если вы расширяете свою библиотеку и вам нужно принять параметры конфигурации, она будет вам доступна. Однако это больше дизайн, чем технический подход.

2
ответ дан 30 November 2019 в 16:18
поделиться

Проблема здесь в том, что глобальные / файловые статические переменные в C должны иметь значение, известное во время компиляции. Это означает, что вы не можете использовать пользовательскую функцию для инициализации значения. Это должно быть постоянное выражение

4
ответ дан 30 November 2019 в 16:18
поделиться
struct A a = { .x = 42 };

Больше участников:

struct Y {
    int r;
    int s;
    int t;
};

struct Y y = { .r = 1, .s = 2, .t = 3 };

Вы также можете сделать

struct Y y = { 1, 2, 3 };

То же самое работает для профсоюзов, и вам не нужно включать всех участников или даже расположите их в правильном порядке.

18
ответ дан 30 November 2019 в 16:18
поделиться

Вы не можете вызывать функцию как initiliazer. Вы должны вызывать ее внутри main.

1
ответ дан 30 November 2019 в 16:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: