String s; & S + 1; Legal? UB?

Consider the following code:

#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; } 

&myAry[numStrs] interesting here: numStrs is 5, so &myAry[numStrs] indicates that it does not exist; the sixth element in the array. There is another example in the above code: myVec.end() , which points to one end of the end of the myVec vector. It is perfectly legitimate to accept the address of this element, which is not there. We know the size of the string , so we know where the address of the 6th element of the array of C-style string should be indicated. As long as we evaluate this pointer and never play it, we are fine. We can even compare it with other pointers to equality. STL does this all the time in algorithms that operate on a number of iterators. The end() iterator points to the end, and the loops continue the loop until the counter != end() .

So now consider the following:

 #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; } 

Is this code legal and well-defined? It’s correctly and clearly defined that the address of an array element is at the end, as in &myAry[numStrs] , so should it be legal and well-defined to pretend that myPtr also an array?

+5
source share
2 answers

It is legal, and not UB, to have a pointer to the "one end" of the array, and any single object can be processed as if it were in an array of length 1; however, you need to use ptr + 1 instead because of the technically &ptr[1] dereferencing, and then take the address. This also applies to &array[size] becoming array + size .

What you have will work as you expect on all platforms that I know about, but given how easy it is to use the uniquely correct form, I see no reason not to.

+12
source

The C ++ standard in 5.6 / 4 "Additive Operators" says:

For these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

The C99 6.5.6 / 7 standard says essentially the same thing.

+5
source

All Articles