2009-10-19 6 views

Répondre

25

Sur la durée de stockage:

2.13.4 chaînes littérales ordinaires et les littéraux de chaîne UTF-8 sont également appelés chaînes littérales aussi étroites. Une « matrice de n const char » étroit type a chaîne littérale , où n est la taille de la chaîne tel que défini ci-dessous, et a durée de stockage statique

lu conjointement avec 3.7.1

3.7.1.

Tous les objets qui n'ont pas de durée de stockage dynamique, n'ont pas de durée de stockage des threads et sont non locaux ont une durée de stockage statique. Le stockage de ces objets doit durer pendant toute la durée du programme (3.6.2, 3.6.3).

Sur Type:

Annexe C

2.13.4 Paragraphe:

changement: Les littéraux de chaîne en const Le type d'une chaîne littérale est changé de "tableau de char" en "tableau de const char." Le type d'un Le littéral littéral char16_t est remplacé par "tableau de const-type_entier" par "tableau de const char16_t". Le type d'un littéral de chaîne char32_t est remplacé par "tableau de type-entier" par "tableau de const char32_ - t.» Le type de change une grande chaîne littérale de « tableau de wchar_t » à « tableau de const wchar_t »

Justification:. Cela évite d'appeler une fonction inappropriée surcharge, ce qui pourrait attendre de pouvoir modifier sa argument.

Effet sur la caractéristique d'origine: Passer à la sémantique d'une entité bien définie. Difficulté de conversion: Transformation syntaxique simple, car les chaînes littérales peuvent être converties en char *; (4.2). Les cas les plus courants sont traités par une conversion standard nouvelle mais obsolète: char * p = "abc"; // valide en C, déconseillé en C++ char * q = expr? "abc": "de"; // valable en C, C++ non valide dans

Comment largement utilisé: Les programmes qui ont une raison légitime pour traiter des chaînes littérales comme pointeurs potentiellement mémoire modifiables sont probablement rares.

Dynamiquement alloué (le mot « tas » n'est jamais utilisé dans le contexte d'une zone de mémoire AFAIK dans la norme) mémoire exige un appel de fonction qui peut se produire dès main beaucoup après la mémoire statique est allouée.

+0

+1 pour la réponse correcte, mais votre citation de Standard n'est pas exacte (au moins 2.13.4). –

+0

Une citation sur l'utilisation standard de C-Strings peut également être utile. Dans le monde C, il est plus standard de renvoyer un pointeur char * dynamiquement alloué et qui doit donc être libéré. Si vous ne suivez pas cette convention, votre code ne fonctionnera pas bien avec les bibliothèques existantes qui assument cette convention. –

+1

@Kirill V. Lyadvinsky: Ceci est à partir du projet de C++ 0x N-4411 (mentionné dans un commentaire par moi). – dirkgently

13

Ce code est parfaitement valide et conforme. Le seul "gotcha" serait de s'assurer que l'appelant n'essaie pas de libérer la chaîne.

+0

"Ce code est parfaitement valide et conforme." Pourquoi? –

+0

Il n'y a pas besoin. Les littéraux sont 'const char []' qui ne sont jamais alloués par tas. Le pointeur retourné sera valide pendant toute l'exécution du programme. –

+1

Il n'y a pas de '' const char [] '" –

11

Ce code est valide et conforme aux normes.

Les littéraux de chaîne sont stockés dans une mémoire en lecture seule et la fonction obtient simplement l'adresse de la chaîne choisie.

norme C de (2.13.4) dit:

Un « tableau de n const char » string est de type littéral ordinaire et la durée statique de stockage

La clé pour comprendre votre problème ici, est la durée de stockage statique: les littéraux de chaîne sont alloués lors du lancement de votre programme, et durent pendant toute la durée du programme. Votre fonction reçoit juste l'adresse et la renvoie.

5

Techniquement Oui c'est valide.
Les chaînes ont une durée de stockage statique.

Mais ce n'est pas toute l'histoire.

Ce sont des C-Strings. La convention dans C-Libraries et funcctions est de retourner une chaîne allouée dynamiquement qui devrait être libérée. C'est-à-dire qu'un pointeur renvoyé renvoie implicitement la propriété à l'appelant (comme d'habitude en C il y a aussi des exceptions).

Si vous ne respectez pas ces conventions, vous risquez de dérouter un grand nombre de développeurs expérimentés qui attendent cette convention. Si vous ne respectez pas cette attente standard, cela devrait être bien documenté dans le code.

Aussi c'est C++ (selon vos tags). Il est donc plus conventionnel de retourner une chaîne std :: string. La raison en est que le transfert de propriété via les pointeurs n'est qu'implicite (et que cela a conduit à beaucoup d'erreurs dans le code C alors que l'attente ci-dessus était cassée mais documentée, malheureusement le document n'a jamais été lu par l'utilisateur). En utilisant une chaîne std :: vous passez un objet et il n'est plus question de propriété (le résultat est retransmis en valeur et donc le vôtre), mais comme il s'agit d'un objet il n'y a pas de questions ou problèmes d'allocation de ressources .

Si vous vous inquiétez de l'efficacité, je pense que c'est une fausse préoccupation.

Si vous voulez que cela pour l'impression via flux il existe déjà une convention standard pour le faire:

std::cout << std::boolalpha << false << std::endl; 
std::cout << std::boolalpha << true << std::endl; 
Questions connexes