std::map, does the standard define what to do here?

Z

Zachary Turner

std::map<int, int> test;
bool eq1 = false;
bool eq2 = false;

test[5] = 7;
std::map<int, int>::iterator iter = test.begin();
std::map<int, int>::iterator iterEnd = test.end();

eq1 = (iter == iterEnd);
--iter;
eq2 = (iter == iterEnd);

I suspect the answer is that no, decrementing the begin iterator is
undefined, but just looking for confirmation. In Visual C++, after
this code executes eq1 is false and eq2 is true(!), and in fact in
Visual C++ you can decrement this iterator indefinitely and it will
just cycle through the tree forever.
 
P

peter koch

std::map<int, int> test;
bool eq1 = false;
bool eq2 = false;

test[5] = 7;
std::map<int, int>::iterator iter = test.begin();
std::map<int, int>::iterator iterEnd = test.end();

eq1 = (iter == iterEnd);
--iter;
eq2 = (iter == iterEnd);

I suspect the answer is that no, decrementing the begin iterator is
undefined, but just looking for confirmation.  In Visual C++, after
this code executes eq1 is false and eq2 is true(!), and in fact in
Visual C++ you can decrement this iterator indefinitely and it will
just cycle through the tree forever.
You are correct - it is undefined behaviour, so don't do it.

/Peter
 
R

rishabh

std::map<int, int> test;
bool eq1 = false;
bool eq2 = false;
test[5] = 7;
std::map<int, int>::iterator iter = test.begin();
std::map<int, int>::iterator iterEnd = test.end();
eq1 = (iter == iterEnd);
--iter;
eq2 = (iter == iterEnd);
I suspect the answer is that no, decrementing the begin iterator is
undefined, but just looking for confirmation.  In Visual C++, after
this code executes eq1 is false and eq2 is true(!), and in fact in
Visual C++ you can decrement this iterator indefinitely and it will
just cycle through the tree forever.

You are correct - it is undefined behaviour, so don't do it.

/Peter

eq2 is never true even you decrease it more than 1 time.
 
R

Richard Herring

In message
std::map<int, int> test;
bool eq1 = false;
bool eq2 = false;
test[5] = 7;
std::map<int, int>::iterator iter = test.begin();
std::map<int, int>::iterator iterEnd = test.end();
eq1 = (iter == iterEnd);
--iter;
eq2 = (iter == iterEnd);
I suspect the answer is that no, decrementing the begin iterator is
undefined, but just looking for confirmation.  In Visual C++, after
this code executes eq1 is false and eq2 is true(!), and in fact in
Visual C++ you can decrement this iterator indefinitely and it will
just cycle through the tree forever.

You are correct - it is undefined behaviour, so don't do it.

eq2 is never true even you decrease it more than 1 time.

What part of "undefined behaviour" don't you understand?

[lib.bidirectional.iterators]

Expression: --r
pre: there exists s such that r == ++s.
 
S

SG

eq2 is never true even you decrease it more than 1 time.

It may be true. The standard doesn't forbid an implementation to make
iterators circular.
It also doesn't require it. It really doesn't matter since it's
undefined behaviour.

Cheers!
SG
 
Z

Zachary Turner

std::map<int, int> test;
bool eq1 = false;
bool eq2 = false;
test[5] = 7;
std::map<int, int>::iterator iter = test.begin();
std::map<int, int>::iterator iterEnd = test.end();
eq1 = (iter == iterEnd);
--iter;
eq2 = (iter == iterEnd);
I suspect the answer is that no, decrementing the begin iterator is
undefined, but just looking for confirmation.  In Visual C++, after
this code executes eq1 is false and eq2 is true(!), and in fact in
Visual C++ you can decrement this iterator indefinitely and it will
just cycle through the tree forever.
You are correct - it is undefined behaviour, so don't do it.

eq2 is never true even you decrease it more than 1 time.

Feel free to try it on Visual Studio 2005, I assure you it most
definitely is true. I have only tried it with a map containing
exactly 1 item, in which case decrementing .begin() DOES EQUAL .end(),
so obviously decrementing it again will yield a valid element, and
decrementing it again will equal end again, ad infinitum.

It's obviously counterintuitive, which is why I assumed that the
standard either a) explicitly requires that such behavior not exist,
in which case that would mean Visual Studio's STL implementation has a
bug, or b) does not specify the behavior, or leaves it undefined, in
which case Visual Studio's STL implementation is fine.
 
J

James Kanze

std::map<int, int> test;
bool eq1 = false;
bool eq2 = false;
test[5] = 7;
std::map<int, int>::iterator iter = test.begin();
std::map<int, int>::iterator iterEnd = test.end();
eq1 = (iter == iterEnd);
--iter;
eq2 = (iter == iterEnd);
I suspect the answer is that no, decrementing the begin
iterator is undefined, but just looking for
confirmation. In Visual C++, after this code executes
eq1 is false and eq2 is true(!), and in fact in Visual
C++ you can decrement this iterator indefinitely and it
will just cycle through the tree forever.
You are correct - it is undefined behaviour, so don't do it.
eq2 is never true even you decrease it more than 1 time.
Feel free to try it on Visual Studio 2005, I assure you it
most definitely is true. I have only tried it with a map
containing exactly 1 item, in which case decrementing .begin()
DOES EQUAL .end(), so obviously decrementing it again will
yield a valid element, and decrementing it again will equal
end again, ad infinitum.
It's obviously counterintuitive, which is why I assumed that
the standard either a) explicitly requires that such behavior
not exist, in which case that would mean Visual Studio's STL
implementation has a bug, or b) does not specify the behavior,
or leaves it undefined, in which case Visual Studio's STL
implementation is fine.

For a weak-enough definition of fine. Generally speaking, VC++
traps this sort of error, at least when compiled with the right
options. (Try it with and std::vector, for example. If the
code doesn't abort, you're not using the right compiler
options.) So I rather suspect that this could be considered a
bug. (I get a runtime error with all of the sequence
containers, but none for the associative containers, with VC++.
I get a runtime error with all of the containers with g++.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top