Si consideri il seguente codice:string s; &s+1; Legale? 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;
}
Di interesse qui è &myAry[numStrs]
: numStrs è uguale a 5, in modo da &myAry[numStrs]
punti a qualcosa che non esiste; il sesto elemento nella matrice. C'è un altro esempio di questo nel codice di cui sopra: myVec.end()
, che indica uno-oltre-la-fine del vettore myVec
. È perfettamente legale prendere l'indirizzo di questo elemento che non esiste. Sappiamo le dimensioni di string
, quindi sappiamo dove deve essere indirizzato l'indirizzo del sesto elemento di una matrice in stile C di string
s. Finché valutiamo questo puntatore e non lo dereferiamo mai, stiamo bene. Possiamo persino confrontarlo con altri indicatori per l'uguaglianza. Lo STL lo fa sempre in algoritmi che agiscono su un intervallo di iteratori. L'iteratore end()
punta oltre la fine e i loop continuano a scorrere mentre un contatore != end()
.
Così ora considerare questo:
#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;
}
È questo il codice legale e ben definito? È legale e ben definito prendere l'indirizzo di un elemento della matrice oltre la fine, come in &myAry[numStrs]
, quindi dovrebbe essere legale e ben definito fingere che myPtr
sia anche un array?
+1 per la precisione tecnica. Non solo è facile farlo correttamente, ma evita anche ulteriori insidie con il fatto che l'operatore e 'sovraccarico (è brutto sovraccaricarlo, sì, ma questo mostra come si trascinino solo le dipendenze). Meglio restare senza comportamenti indefiniti. –