J'obtiens une erreur à la ligne 6 (initialisez 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 qu'il s'agit d'une version simplifiée d'un plus grand projet multi-fichiers sur lequel je travaille. Le but était d'avoir une seule constante dans le fichier objet, que plusieurs fichiers pourraient utiliser pour initialiser une structure d'état. Comme il s'agit d'une cible intégrée avec des ressources limitées et que la structure n'est pas si petite, je ne veux pas plusieurs copies de la source. Je préfère ne pas utiliser:
#define foo_init { 1, 2, 3 }
J'essaie également d'écrire du code portable, j'ai donc besoin d'une solution valide C89 ou C99.
Cela a-t-il à voir avec les ORG dans un fichier objet? Que les variables initialisées vont dans un ORG et sont initialisées en copiant le contenu d'un deuxième ORG?
Peut-être que j'aurai juste besoin de changer de tactique et qu'une fonction d'initialisation fasse toutes les copies au démarrage. À moins qu'il n'y ait d'autres idées là-bas?
la source
enum { N = 5 };
est une manière sous-estimée de déclarer des constantes sans avoir à recourir à#define
.static int* ptr = malloc(sizeof(int)*5);
mais ce n'est PAS une erreurstatic int* ptr; ptr = malloc(sizeof(int)*5);
:: DC'est une limitation de la langue. Dans la section 6.7.8 / 4:
Dans la section 6.6, la spécification définit ce qui doit être considéré comme une expression constante. Nulle part il n'indique qu'une variable const doit être considérée comme une expression constante. Il est légal pour un compilateur d'étendre this (
6.6/10 - An implementation may accept other forms of constant expressions
) mais cela limiterait la portabilité.Si vous pouvez changer
my_foo
pour qu'il n'ait pas de stockage statique, tout ira bien:la source
static const int x = 3; static int y = x;
.Juste pour illustration par comparaison et contraste Le code provient de http://www.geeksforgeeks.org/g-fact-80/ / Le code échoue dans gcc et passe dans g ++ /
la source
C'est un peu vieux, mais j'ai rencontré un problème similaire. Vous pouvez le faire si vous utilisez un pointeur:
la source
gcc 7.4.0 ne peut pas compiler les codes comme ci-dessous:
constchar.c: 3: 21: erreur: l'élément d'initialisation n'est pas constant const char * str2 = str1;
En fait, une chaîne "const char *" n'est pas une constante de compilation, elle ne peut donc pas être un initialiseur. Mais une chaîne "const char * const" est une constante à la compilation, elle devrait pouvoir être un initialiseur. Je pense que c'est un petit inconvénient de CLang.
Un nom de fonction est bien sûr une constante de compilation, donc ce code fonctionne:
la source
str1
n'est pas une expression selon 6.7.9 Initialisation , paragraphe 4 : "Toutes les expressions dans un initialiseur pour un objet qui a une durée de stockage statique ou de thread doivent être des expressions constantes ou des chaînes littérales."