Подтвердить что ты не робот

GCC отсутствует привязка вокруг инициализатора

У меня есть эта структура в C ниже, которую я хочу инициализировать на все ноль. Как избавиться от предупреждения о отсутствующих брекетах?

typedef struct {
    uint32_t incoming[FRAME_TYPE_MAX];
    uint32_t outgoing[FRAME_TYPE_MAX];
    uint32_t timeouts;
    uint32_t crc_errors;
} pkt_t;

static pkt_t stats = {0};
4b9b3361

Ответ 1

Это ошибка GCС# 53119:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119

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

Ответ 2

Поскольку ваш первый член в структуре - это массив, который вам нужен:

static pkt_t stats = {{0}};

Внешние фигурные скобки для структуры, внутренние фигурные скобки для массива. Тем не менее, есть много других способов обмануть этого кота. (например, статика уже установлена ​​до нуля)

Ответ 3

Если это глобальная переменная или локальная статическая, она автоматически инициализируется. Итак, просто:

static pkt_t stats;

Ответ 4

Один из способов - инициализировать каждый член структуры внутри фигурных скобок, а не полагаться на неявное заполнение нуля. Для членов массива вам нужен другой {}, который, вероятно, вызывает предупреждение. Другим является просто отключить предупреждение, хотя это не рекомендуется, так как оно также может ловить законные ошибки.

Ответ 5

Установите этот флаг компилятора gcc: -Wno-пропавшая-распорка

Ответ 6

От "info gcc"

Как расширение GNU, GCC позволяет инициализировать объекты со статической продолжительностью хранения сложными литералами (что невозможно в ISO C99, поскольку инициализатор не является константой). Он обрабатывается так, как если бы объект был инициализирован только с включенным списком скобок, если типы составного литерала и объекта совпадают. Список инициализаторов составного литерала должен быть постоянным. Если инициализированный объект имеет тип массива неизвестного размера, размер определяется размером составного литерала.

 static struct foo x = (struct foo) {1, 'a', 'b'};
 static int y[] = (int []) {1, 2, 3};
 static int z[] = (int [3]) {1};

Вышеуказанные строки эквивалентны следующим образом:

 static struct foo x = {1, 'a', 'b'};
 static int y[] = {1, 2, 3};
 static int z[] = {1, 0, 0};

Возможно, вы сможете объединить эти инициализаторы, чтобы разрешить gcc-специфическую инициализацию ваших массивов, не указывая каждый элемент в массиве. Или... вы можете установить флаг и инициализировать его во время выполнения, если это необходимо, или... вы можете узнать, находится ли переменная в BSS или нет и может быть автоматически обнулена (это в стеке в функции или в глобальной памяти).

Ответ 7

#define FRAME_TYPE_MAX 3

typedef struct {
    uint32_t incoming[FRAME_TYPE_MAX];
    uint32_t outgoing[FRAME_TYPE_MAX];
    uint32_t timeouts;
    uint32_t crc_errors;
} pkt_t;

static pkt_t stats1= { .incoming={5,6,20},
                       .outgoing={0,0,0},
                       .timeouts=0,
                       .crc_errors=0
                       };

static pkt_t stats2= { {5,6,20},
                       {0,0,0},
                       0,
                       0
                       };

static pkt_t stats3= {{0}};

pkt_t stats4 ;   // global


int main(void)
{

    stats1.incoming[0]= 35;
    stats1.timeouts=25;
    stats2.incoming[2]=10;  
    stats3.outgoing[2]=10;  
    stats4.timeouts=10;
    for (;;);
    }

Ответ 8

Если у вас все еще есть радость от версии gcc, которая опускает это ложное предупреждение, со структурой вроде этого в вопросе вы можете избежать этой проблемы с помощью простой реструктуризации, например:

typedef struct {
    uint32_t timeouts;
    uint32_t crc_errors;
    uint32_t incoming[FRAME_TYPE_MAX];
    uint32_t outgoing[FRAME_TYPE_MAX];
} pkt_t;

static pkt_t stats = {0};