J'ai cette structure en C ci-dessous que je veux initialiser à zéro. Comment puis-je me débarrasser de l'avertissement d'accolades manquantes?
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};
Il s'agit du bogue GCC # 53119:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
Si vous souhaitez le voir résolu, publiez un suivi du rapport de bogue indiquant que c'est un problème pour vous.
Puisque votre premier membre dans la structure est un tableau, vous avez besoin:
static pkt_t stats = {{0}};
Les accolades externes sont pour la structure, les accolades internes sont pour le tableau. Cependant, il existe de nombreuses autres façons d'écorcher ce chat. (par exemple, la statique est déjà initialisée à zéro)
S'il s'agit d'une variable globale ou d'une variable statique locale, elle est automatiquement initialisée. Donc, simplement:
static pkt_t stats;
Une façon consiste à initialiser chaque membre de la structure à l'intérieur des accolades, plutôt que de compter sur le remplissage implicite du zéro. Pour les membres du tableau, vous avez besoin d'un autre {} qui est probablement à l'origine de l'avertissement. Une autre consiste à désactiver simplement l'avertissement, bien que cela ne soit pas recommandé car il peut également détecter des bugs légitimes.
Définissez cet indicateur de compilateur gcc: -Wno-missing-braces
De "info gcc"
En tant que GNU, GCC permet l'initialisation d'objets avec une durée de stockage statique par des littéraux composés (ce qui n'est pas possible dans ISO C99, car l'initialiseur n'est pas une constante). Il est traité comme si le l'objet a été initialisé uniquement avec la liste entre crochets si les types du littéral composé et de l'objet correspondent. La liste d'initialisation du littéral composé doit être constante. Si l'objet en cours d'initialisation a un type de tableau de taille inconnue, la taille est déterminée par le composé taille littérale.
static struct foo x = (struct foo) {1, 'a', 'b'};
static int y[] = (int []) {1, 2, 3};
static int z[] = (int [3]) {1};
Les lignes ci-dessus sont équivalentes aux suivantes:
static struct foo x = {1, 'a', 'b'};
static int y[] = {1, 2, 3};
static int z[] = {1, 0, 0};
Vous pourrez peut-être combiner ces initialiseurs pour permettre l'initialisation spécifique à gcc de vos tableaux sans avoir à spécifier chaque élément du tableau. Ou ... vous pouvez définir un indicateur et l'initialiser au moment de l'exécution si nécessaire, ou ... vous pouvez découvrir si la variable est en BSS ou non et peut être automatiquement mise à zéro (est-ce sur la pile dans une fonction ou dans la mémoire globale ).
Si vous avez toujours la joie d'être sur une version gcc qui omet ce faux avertissement, avec une structure comme celle-ci dans la question, vous pouvez éviter ce problème avec une restructuration simple comme celle-ci:
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};
#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 (;;);
}