Différence entre const char * et const char *
Quelqu'un pourrait-il expliquer la différence dans la façon dont les 2 extraits de code sont traitées ci-dessous? Ils ont certainement de la compilation de différentes assemblée de code, mais je vais essayer de comprendre comment le code peut agir différemment. Je comprends que les littéraux de chaîne sont jetés dans la mémoire en lecture seule et sont effectivement statique, mais comment cela diffère de la statique explicite ci-dessous?
struct Obj1
{
void Foo()
{
const char* str( "hello" );
}
};
et
struct Obj2
{
void Foo()
{
static const char* str( "hello" );
}
};
source d'informationauteur Will MacDonagh
Vous devez vous connecter pour publier un commentaire.
Avec votre version statique il n'y aura qu'une seule variable qui sera stocké quelque part et à chaque fois que la fonction est exécutée exactement la même variable sera utilisée. Même pour les appels récursifs.
La non-version statique seront stockées sur la pile pour chaque appel de fonction, et sont détruits après chaque.
Maintenant, votre exemple est un peu compliqué en ce qui concerne ce que le compilateur ne fait alors, regardons un cas plus simple d'abord:
Puis l'une des principales quelque chose comme ceci:
imprime
alors qu'avec
il permet d'imprimer
Maintenant avec votre exemple, vous avez un const, de sorte que la valeur ne peut pas être modifié de sorte que le compilateur pourrait jouer quelques tours, alors qu'il n'a souvent pas d'effet sur le code généré, mais permet au compilateur de détecter les erreurs. Et puis vous avez un pointeur, et l'esprit que la statique a des effets sur le pointeur lui-même, et non pas sur la valeur des points. Ainsi, la chaîne "bonjour" à partir de votre exemple sera probablement placé dans le .segment de données de votre binaire, et une seule fois et de vivre aussi longtemps que le programme de vie,indépendante de la statique .
Une variable statique locale est initialisé la première fois sa définition est rencontré, mais pas détruits lorsque la fonction se termine. Donc, il garde sa valeur entre les appels de la fonction.
Dans le cas d'une
const
ce n'est pas du tout utile - au moins, aussi longtemps que la construction de la valeur de la constante est comme négligeable en terme de performance que l'assignation d'une adresse. (Si leconst
objet n'est pas une expression constante, ou l'expression prend beaucoup de ressources afin de créer - comme dansconst Foo bar = foobar();
oùfoobar()
peut prendre beaucoup de temps, la différence peut devenir important.)Où il y a une différence, c'est quand vous voulez retourner l'objet par référence ou pointeur: Vous ne pouvez pas retourner une référence ou un pointeur vers un objet local, sauf si c'est un objet statique. (Merci à Matthieu pour le rappeler.) Toutefois, lorsque vous souhaitez l'utiliser, vous devez garder à l'esprit que les locaux de la statique sont intrinsèquement thread-dangereux.
J'ai découvert que certains compilateurs traiter les deux différemment.
La version avec
const char *
vont copier les données à partir d'un emplacement en lecture seule à une variable sur la pile.La version avec
static const char *
références données dans l'emplacement en lecture seule (pas de copie).J'ai découvert cette différence en passant à travers l'ensemble du code d'une fonction à l'aide du débogueur. Je vous suggérons d'imprimer le code assembleur ou pas à travers, à l'assemblée, le niveau de langue, avec un débogueur pour trouver l'exacte vérité.
Alors qu'il y a une différence technique, en termes d'utilisation et d'effet de vos deux exemples sont identiques.
Plus en détail, l'utilisation de la
static
mot clé s'applique à le pointeur vers la chaîne de caractères littérale, de ne pas le littéral de chaîne elle-même. Le pointeur dans l'exemple 1 sera placé sur la pile, le pointeur dans l'exemple de deux doit être placée avec les variables statiques.Je serais surpris si ils ne sont pas obtenir optimisés pour la même chose.