Reputation: 27133
I'm wondering if this is defined:
vector<int> v;
v.push_back(1337);
int * p1 = &*vi.end();
(Update 1 If this is undefined, I'd like to know more about exactly where my error is. For example, perhaps the reference int &r = &*(v.data()+v.size())
is legal in general, but *end()
isn't required to return that. )
(Update 2 I'm really just curious about the pedantic language-lawyer question as to what can be defined. I have no difficulty coding uncontroversial workarounds :-) )
Anyway, of course, using an end-iterator like this looks bad. But first, consider this:
int array[3];
int * p2 = array + 3;
Clearly p2
is defined.
The, according to this answer, p2 is equivalent to p3 in this code: (if you're using C99):
int array[3];
int * p2 = array + 3;
int * p3 = &array[3]; // looks bad, but OK in C99
(I'm more curious about C++ though, and a comment to that answer implies that C++ allows it also. So, the above C99-compatible code is defined in C++.)
Moving closer to C++, I think I can write this:
int & r1 = *p3;
I agree that r1
looks really bad. And certainly, it would be UB if we did something like int x= r1;
. That is UB because it involves an lvalue-to-rvalue conversion. But can we say that r1
is still just an lvalue? And therefore we can take its address?
int * p3 = &r1;
If all this is valid, then we can argue that a one-past-the-end reference is generally valid - for C-arrays at least. So, what can we say about *v.end()
?
The operator*()
method returns an int&
reference. Does the standard require that it return one of these one-past-the-end references that we are allowed to take the address of?
Bonus: what if the vector is empty? In particular, is (&*v.end())==(&*v.begin())
Upvotes: 2
Views: 95
Reputation: 695
v.end() points one beyond the last element. Therefore, dereferencing it is illegal.
You could use *(v.end()-1) to get the last element as long as v.size()>=1.
(Or use &*(v.end()-1) to get a pointer to it.)
Upvotes: -1
Reputation: 275350
No, any *
on v.end()
is illegal.
You can do v.data()+v.size()
instead for a pointer to the end, and v.data()
for a pointer to the beginning.
This is defined even for an empty std::vector
.
Upvotes: 4