3 votes

Valeur construite par défaut std::string c_str()

std::string s1;
std::string s2;
assert(strlen(s1.c_str()) == 0);
assert(s1.c_str() == s2.c_str());

Ces deux affirmations sont-elles toujours vraies ?

J'utilise C++11, et j'ai vérifié la norme, le tableau 63 dans le §21.4.2 dit :

data() un pointeur non nul qui peut être copié et auquel on peut ajouter 0.

size() 0

capacité() une valeur non spécifiée

Je pense c_str() est la même chose que data() . Mais j'ai quelques questions à propos de cette définition.

  1. Est-ce que " CAN ont été ajoutés" == " DOIT et TOUJOURS ont 0 ajouté à celui-ci" ?

  2. Est-ce que tous les std::string construits par défaut partagent le même tampon sous-jacent ?

J'ai testé sur gcc, ces deux affirmations sont vraies. Je me demande si elles sont toujours vraies pour tous les compilateurs ?

5voto

user17732522 Points 943

La première affirmation est garantie de succès. c_str() renvoie toujours un pointeur vers une chaîne de caractères à terminaison nulle dont le contenu est le même que celui de l'objet std::string qui est une chaîne vide pour les deux s1 .

Le succès de la deuxième affirmation n'est pas garanti. Il n'y a rien qui exige que le c_str() renvoyée par un std::string pour être le même si le contenu est le même. Les chaînes construites par défaut ne doivent pas nécessairement partager le même tampon sous-jacent. Il s'agit d'un détail d'implémentation d'une bibliothèque standard particulière. (Je pense que libstdc++ fait quelque chose comme ça en fonction de la configuration pour des raisons de rétrocompatibilité( ?) si je me souviens bien, voir le fichier --enable-fully-dynamic-string configure option).

Notez qu'avant C++11, data() a fait pas ont le même effet que c_str() . data() n'était pas garanti de donner un pointeur sur une chaîne de caractères à terminaison nulle. Si la chaîne était vide, le pointeur qu'elle renvoyait ne pouvait pas être déréférencé. Ainsi, en remplaçant c_str() avec data() dans vos exemples aurait, avant C++11, entraîné un comportement non défini lors de l'appel à strlen .


La formulation " et peut se voir ajouter 0 "est un peu bizarre et je ne suis pas tout à fait sûr de ce qu'il est censé transmettre, mais pour C++11 (projet N3337) data() La valeur de retour de l'option est précisée dans [string.accessors]/1 de sorte que data() + i == &operator[](i) pour tous i dans la gamme [0,size()] et operator[] est spécifié dans [strings.access]/2 pour retourner une référence à un CharT() (c'est-à-dire un caractère nul) pour operator[](size()) sans aucune condition.

La formulation étrange a également été remplacée par une modification rédactionnelle en 2018, voir https://github.com/cplusplus/draft/pull/1879 .

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