220 votes

Erreur « élément initializer n’est pas constante » lorsque vous essayez d’initialiser la variable avec const

J'obtiens une erreur à la ligne 6 (initialiser my_foo à foo_init) du programme suivant et je ne suis pas sûr de comprendre pourquoi.

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;
}

Gardez à l'esprit que c'est une version simplifiée d'un grand, multi-fichier de projet, je travaille sur. Le but était d'avoir une seule constante dans l'objet du fichier, plusieurs fichiers peuvent utiliser pour initialiser une structure de l'etat. Puisque c'est une cible embarquée avec des ressources limitées et la structure n'est pas que les petits, je ne veux pas de copies multiples de la source. Je préfère ne pas l'utiliser:

#define foo_init { 1, 2, 3 }

J'essaie aussi d'écrire du code portable, j'ai donc besoin d'une solution valide C89 ou C99.

Est-ce que avez à faire avec les ORGs dans un fichier de l'objet? Qui a initialisé les variables d'aller dans l'un et ORG sont initialisés en copiant le contenu d'un deuxième ORG?

Je vais peut-être juste besoin de changer ma tactique, et ont une initialisation de la fonction de faire toutes les copies au démarrage. Sauf si il y a d'autres idées?

315voto

AndreyT Points 139512

Il a à voir avec le langage C. En langage C, les objets statiques durée de stockage doit être initialisé avec des expressions constantes ou de l'agrégat des initialiseurs contenant des expressions constantes.

Un "grand" de l'objet n'est jamais une expression constante dans C, même si l'objet est déclaré en tant que const.

En outre, en langage C, le terme "constante" fait référence aux constantes littérales (comme 1, 'a', 0xFF et ainsi de suite) et enum membres. Const qualifiés d'objets (de tout type) sont pas constantes dans le langage C de la terminologie. Ils ne peuvent pas être utilisés dans les initialiseurs d'objets statiques durée de stockage, quel que soit leur type.

Par exemple, ce n'est PAS une constante

const int C = 5; /* `C` is not a constant in C */

Le ci-dessus C serait une constante dans le C++, mais il n'est pas une constante dans C. Donc, si vous essayez de faire

static int j = C; /* ERROR */

vous obtiendrez la même erreur: une tentative d'initialisation d'un objet statique avec un non-constante.

82voto

R Samuel Klatchko Points 44549

C'est une limitation de la langue. Dans la section 6.7.8/4:

Toutes les expressions dans un initialiseur pour un objet statique de la durée de stockage doit être des expressions constantes ou des littéraux de chaîne.

Dans la section 6.6, la spécification définit ce qui doit considéré comme une expression constante. Pas où est-ce qu'une variable const doit être considérée comme une expression constante. Il est légal pour un compilateur pour étendre cette (6.6/10 - An implementation may accept other forms of constant expressions), mais qui limite la portabilité.

Si vous pouvez changer my_foo afin de ne pas avoir de stockage statique, vous seriez d'accord:

int main()
{
    foo_t my_foo = foo_init;
    return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X