Ответ 1
Это ошибка GCС# 53119:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
Если вы хотите, чтобы это было исправлено, опубликуйте отчет об ошибке, указав, что это проблема для вас.
У меня есть эта структура в 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};
Это ошибка GCС# 53119:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
Если вы хотите, чтобы это было исправлено, опубликуйте отчет об ошибке, указав, что это проблема для вас.
Поскольку ваш первый член в структуре - это массив, который вам нужен:
static pkt_t stats = {{0}};
Внешние фигурные скобки для структуры, внутренние фигурные скобки для массива. Тем не менее, есть много других способов обмануть этого кота. (например, статика уже установлена до нуля)
Если это глобальная переменная или локальная статическая, она автоматически инициализируется. Итак, просто:
static pkt_t stats;
Один из способов - инициализировать каждый член структуры внутри фигурных скобок, а не полагаться на неявное заполнение нуля. Для членов массива вам нужен другой {}, который, вероятно, вызывает предупреждение. Другим является просто отключить предупреждение, хотя это не рекомендуется, так как оно также может ловить законные ошибки.
Установите этот флаг компилятора gcc: -Wno-пропавшая-распорка
От "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 или нет и может быть автоматически обнулена (это в стеке в функции или в глобальной памяти).
#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 (;;);
}
Если у вас все еще есть радость от версии 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};