L'initialisation de Const Struct avec d'autres Const Struct Instances
Je suis curieux de savoir pourquoi l'extrait de code suivant ne compile pas:
typedef struct Foo {
int a;
int b;
} Foo;
static const Foo FooZero = { 0, 0 };
typedef struct Bar {
Foo foo;
int c;
} Bar;
static const Bar BarZero = { FooZero, 0 };
Il se plaint de l'utilisation de FooZero
, indiquant que FooZero
n'est pas un Compile-Time Constant
Mais n'est-ce pas? Ce que je ne suis pas à comprendre ici?
Évidemment, je ne peux simplement remplacer l'utilisation de FooZero
dans l'initialiseur, avec { 0, 0 }
- mon but, en posant la question n'est pas comment contourner le problème - j'essaie de comprendre la raison sous-jacente pourquoi FooZero
n'est pas, en fait, une constante de compilation.
Grâce
double possible de Erreur "initialiseur élément n'est pas constante" lors de l'initialisation de variable const
stackoverflow.com/questions/3025050/... c'est une très bonne explication, l'encapsulation de ce que j'allais écrire
Bah - Merci pour le lien. Cependant, ma question est "pourquoi est-ce si". Je sens la réponse à la question que vous avez cité n'a pas vraiment répondu à ma question "pourquoi", ils ne font que souligner ce que je sais déjà à être le cas.
Vous ne pouvez pas se déplacer sans l'aide d'une fonction en C ? Aussi FooZero n'est pas de compiler constante de temps. C'est ce que à la fois les liens de dire.
stackoverflow.com/questions/3025050/... c'est une très bonne explication, l'encapsulation de ce que j'allais écrire
Bah - Merci pour le lien. Cependant, ma question est "pourquoi est-ce si". Je sens la réponse à la question que vous avez cité n'a pas vraiment répondu à ma question "pourquoi", ils ne font que souligner ce que je sais déjà à être le cas.
Vous ne pouvez pas se déplacer sans l'aide d'une fonction en C ? Aussi FooZero n'est pas de compiler constante de temps. C'est ce que à la fois les liens de dire.
Also FooZero is not compile time constant.
Oui, encore, je le sais. Ma question est POURQUOI est-ce donc? Pourquoi la mécanique de la langue tel que cela est vrai?
OriginalL'auteur Steve | 2011-09-12
Vous devez vous connecter pour publier un commentaire.
Il a surtout à voir avec l'initialisation.
La initialisé les variables ne sont généralement pas initialisé par le code qui dit "mettez cette valeur à cet endroit", mais par une définition qui permet de charger une valeur spécifique de la gamme, la
.data
resp..rodata
segment, à l'emplacement mémoire où il est censé être. Ceci est fait par le système d'exploitation du fichier loader. (Strictement parlant, ce n'est pas une propriété de C, qui ne sait rien à ce sujet, mais de l'environnement d'exécution.)Cela dit, il n'est pas possible de raconter une partie de cette zone de mémoire qui doit être copié dans un autre. Mais il serait possible de te compilateur itselfs reconnaît l'intention de la déclaration et met les mêmes valeurs pour diefferent endroits. Mais ce serait sans doute trop de "deviner".
Dans votre cas N'est-il pas un pointeur vers
FooZero
peut-être une meilleure solution? Les valeurs sont les mêmes...Ou dans l'autre sens:
Dans le premier cas, vous devez accéder à
BarZero.foo
'composants avec->
(commeBarZero.foo->a
),dans le deuxième cas, vous avez accès à
FooZero
'composants avec->
(commeFooZero->a
).comme ils sont tous déclarés
const
, personne ne devrait (normalement) être en mesure de le modifier.OriginalL'auteur glglgl
Dans le langage C un
const
oustatic const
valeur n'est pas considérée comme une "compilation constante de temps", alors queest considéré comme une constante de compilation. Vous me direz "mais, Mais, il dit même
const
! Comment peut-il ne pas être une constante??" Et en effet, le langage dit que vous ne pouvez pas modifier la valeur d'une chose que vous spécifiez commeconst
, mais vous ne pouvez pas l'utiliser comme un initialiseur. Vous pouvez demander pourquoi tout ce que vous voulez, cela ne va pas changer la façon dont le langage définit elle - même si votre compilateur peut vous donner une option pour changer ce comportement, et il n'est pas trop difficile à contourner, en tout cas.Je pense qu'il est assez commun pour les compilateurs C pour traiter les constantes statiques comme les variables globales, c'est - à fait d'allouer de l'espace pour une variable (qui ne change jamais), plutôt que le programme de la dur des valeurs dans le code de l'ordinateur, comme il le ferait si vous avez un
#define
. Dans ce cas, les constantes, en effet, que le compilateur dit, ne sont pas des constantes de compilation, même s'ils sont des constantes pour toutes les autres fins après ils sont initialisées (à l'exécution).You can ask why all you like, it won't change how the language defines it.
Vrai, mais j'ai peut-être édifiés de la réponse. ---although they are constants for all other purposes after they are initialised (at runtime).
Intéressant. Lorsque, précisément, sont-ils initialisé? Lors de la première utilisation? --- Aussi, merci pour le#define
pointeur.Merci pour le commentaire - je pense que votre question sur l'initialisation a été répondu par glglgl - initialisation se produit lors du chargement de données dans le programme au démarrage.
OriginalL'auteur Brian L