Consultez le code suivant:chaîne s; &s+1; Légal? UB?
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string myAry[] =
{
"Mary",
"had",
"a",
"Little",
"Lamb"
};
const size_t numStrs = sizeof(myStr)/sizeof(myAry[0]);
vector<string> myVec(&myAry[0], &myAry[numStrs]);
copy(myVec.begin(), myVec.end(), ostream_iterator<string>(cout, " "));
return 0;
}
d'intérêt est ici &myAry[numStrs]
: numStrs est égal à 5, donc &myAry[numStrs]
des points à quelque chose qui n'existe pas; le sixième élément dans le tableau. Il y a un autre exemple de ceci dans le code ci-dessus: myVec.end()
, qui pointe à un-passé-le-fin du vecteur myVec
. Il est parfaitement légal de prendre l'adresse de cet élément qui n'existe pas. Nous connaissons la taille de string
, donc nous savons où l'adresse du 6ème élément d'un tableau de type C de string
doit pointer. Tant que nous évaluons seulement ce pointeur et ne le déréférons jamais, nous allons bien. Nous pouvons même le comparer à d'autres indicateurs d'égalité. La STL le fait tout le temps dans des algorithmes qui agissent sur une gamme d'itérateurs. L'itérateur end()
dépasse la fin et les boucles continuent à boucler pendant qu'un compteur != end()
.
Alors maintenant, considérez ceci:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string myStr = "Mary";
string* myPtr = &myStr;
vector<string> myVec2(myPtr, &myPtr[1]);
copy(myVec2.begin(), myVec2.end(), ostream_iterator<string>(cout, " "));
return 0;
}
Est-ce code juridique et bien défini? Il est légal et bien défini de prendre l'adresse d'un élément de tableau après la fin, comme dans &myAry[numStrs]
, alors devrait-il être légal et bien défini de prétendre que myPtr
est aussi un tableau?
+1 pour plus de précision. Non seulement il est facile de le faire correctement, mais il évite aussi d'autres pièges avec l'opérateur & 'étant surchargé (il est mauvais de le surcharger, oui, mais cela montre comment il suffit de faire glisser les dépendances). Le mieux est de rester libre de tout comportement indéfini. –