J'aurais attendu que le code suivant donne une erreur de segmentation (ou sinon ub): c'est parce que Cependant, L'extrait ci-dessus semble émettre la chaîne comme prévu comme prévu (et j'ai confirmé le comportement en imprimant également la valeur du pointeur). P> existe une règle d'initialisation statique que je 'M Manquant ici, cela permet à Ceci est venu sur résolution de variable statique à la limite de la construction , où un répondeur a affirmé que l'utilisation de t code> est initialisé avant
STR code>. Je m'attendrais à
str code> pour contenir la valeur
(chartons *) 0 code> en raison d'une initialisation zéro. Mon interprétation de
[C ++ 11: 3.6.2 / 2] code> prend en charge cela. P>
str code> d'être initialisé avant que
t code> commence la construction? Où est-il dans la norme? P>
chartons * code> plutôt que
std :: string code> pour un global statique évite le fiasco d'ordre d'initialisation statique. Je suis en désaccord, mais maintenant je ne suis pas si sûr ... sup> p> p>
4 Réponses :
Les types intégrés ne sont pas initialisés du tout, au sens normal. Communément, leurs contenus initiaux sont cartographiés directement à partir d'une région spéciale du binaire dans le cadre de la chargement. P>
S'avère qu'ils sont. Cet acte est apparemment appelé "initialisation constante".
@LighessRacksinorbit: logiquement, oui. Physiquement, vous ne trouverez aucun code nulle part indiquant: "Attribuez l'adresse de cette chaîne littérale à str code>". C'est ce que je voulais dire, "au sens normal".
hoche la tête i> merci. Cherchait cependant de raisonner standard, donc logique.
str code> est initialisé par une expression constante et
const char * code> est un type de pod (C ++ 03 termes, mais c ++ 11 il est analogue, mais avec Termes et cas de manière différente des cas plus autorisés). Une telle initialisation est effectuée dans statique em> phase d'initialisation et la phase d'initialisation statique em> n'a pas de problème de commande. Cela arrive avant tout initialisation dynamique em>.
t code> est initialisé dans la phase d'initialisation dynamique em>. p>
Est-ce couvert par le passage que j'ai cité? Ou ailleurs?
@Light oui vous avez cité le texte C ++ 11.
Je ne suis pas convaincu que "STR est initialisé par une expression constante". Il faut une adresse de littéral de chaîne, ce qui n'est certainement pas une expression constante. Par conséquent, SH devrait avoir une initialisation dynamique. Cependant, les implémentations sont autorisées (3.6.2 / 3) pour l'initialiser de manière statique.
@Timo: Je suis sûr qu'un littéral à chaîne est une expression constante. Tous les littéraux doivent être ( 5.19 / 2 code>). Que la valeur du pointeur peut changer entre les constructions et les invocations n'est pas pertinente.
char const* str = "Test string"; is done by the compiler/linker, so it exists in its "initialized state" before the program even starts to run.
Je pense que je l'ai trouvé; Ce qui se passe ici n'est pas tant sur le type intégré, mais sur l'initialiseur constant: P>
[C ++ 11: 3.6.2 / 2]: Code> Les variables avec durée de stockage statique (3.7.1) ou la durée du stockage de thread (3.7.2) doivent être initialisées zéro (8.5) avant toute autre initialisation a lieu. P>
initialisation constante em> est effectuée: strong> p>
- Si chacun expression complète em> (y compris les conversions implicites) qui apparaît dans l'initialisateur d'une référence avec une durée de stockage statique ou de thread est une expression constante (5,19) et la référence est liée à une adressage de la lvalue un objet avec durée de stockage statique ou à un temporaire (voir 12.2); li>
- Si un objet avec une durée de stockage statique ou de thread est initialisé par un appel de constructeur, si le constructeur est un constructeur
consexpr code>, si tous les arguments du constructeur sont des expressions constantes (y compris des conversions), et si, après Substitution d'invocation de fonction (7.1.5), chaque appel de constructeur et expression complète dans Les initialiseurs Mem-initialiseurs em> et dans les initialiseurs EM> em> pour les membres de données non statiques sont une expression constante; li>
- Si un objet avec une durée de stockage statique ou de fil n'est pas initialisé par un appel de constructeur et si chaque expression complète em> qui apparaît dans son initialiseur est une expression constante. strong> < / li> ul>
ensemble, l'initialisation zéro em> et une initialisation constante s'appelle une initialisation statique; Toute autre initialisation est l'initialisation dynamique. L'initialisation statique doit être effectuée avant que toute initialisation dynamique n'a lieu. Strong> [..] p> blockQuote>
Cette phrase finale semblerait remplacer les règles de séquençage ultérieures, ce qui rend cette commande s'appliquer sur des unités de traduction. P>
Votre dernière conclusion est incorrecte. Seule initialisation dynamique peut être "non ordonnée" ou "commandée". Ces deux termes ne s'appliquent pas à l'initialisation statique. La commande n'est pas un problème ici.
@ Johannesschab-LitB: OK, que diriez-vous des deux phrases précédentes, qui répètent à peu près la même règle, mais sans le mot "non ordonné"?
Ils disent que "l'initialisation statique doit être effectuée avant que toute initialisation dynamique n'a lieu.". C'est une exigence difficile. Il n'y a pas de place pour les implémentations pour ne pas suivre cette exigence.
@ Johannesschab-Litb: Hmm ... Je suppose .. va revisiter
@ Johannesschab-Litb: Gotcha.
Voir Stackoverflow.com/q/790687/34509 pour une question qui a actuellement accepté mais malheureusement mauvaise réponse.
@ Johannesschab-LitB: En effet.