Topic: On std::pair and undefined behavior for singular iterators


Author: joaquin@tid.es (Joaqu?n M? L?pez Mu?oz)
Date: Thu, 22 Jul 2004 18:54:12 GMT
Raw View
Consider the following:

int main()
{
  typedef set<int> int_set;

  int_set::iterator it0; // it0 holds a singular value
  int_set::iterator it1; // same thing

  int_set s;

  it0=s.begin(); // OK to assign a non-singular value to it0
  it1=s.end();   // OK too
}

As per std 24.1.5, this program is correct (AFAICS). Now
consider the following seemingly innocent variant:

int main()
{
  typedef set<int> int_set;

  pair<int_set::iterator,int_set::iterator> p; // problem here

  int_set s;

  p.first=s.begin();
  p.second=s.end();
}

The default constructor of p behaves (according to std 20.2.2.2)
like this:

pair(): first(int_set::iterator()), second(int_set::iterator()) {}

and here we hit a problem, since p.first and p.last are
copy-constructed from singular iterators, which is undefined!!

So I've got three questions:

1. Is my analysis correct in that the second program engenders
undefined behavior?
2. If so, isn't this a little too restrictive? The second variant
seems a straightforward reformulation of the first one, so I found
the issue annoying. Would be there a problem in allowing an
iterator to be copy-constructed from a singular iterator?
3. Or, if we are to blame std::pair instead, why the default ctor is
defined in this way? I don't see a problem in requiring that
default construction behave like

pair(): first(), second() {}

rather than what the std says. Could this qualify as a DR?

Regards,

Joaqu   n M L   pez Mu   oz
Telef   nica, Investigaci   n y Desarrollo

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tom_usenet@hotmail.com (tom_usenet)
Date: Fri, 23 Jul 2004 16:12:11 GMT
Raw View
On Thu, 22 Jul 2004 18:54:12 GMT, joaquin@tid.es (Joaqu?n M? L?pez
Mu?oz) wrote:

>Consider the following:

>int main()
>{
>  typedef set<int> int_set;
>
>  pair<int_set::iterator,int_set::iterator> p; // problem here
>
>  int_set s;
>
>  p.first=s.begin();
>  p.second=s.end();
>}
>
>The default constructor of p behaves (according to std 20.2.2.2)
>like this:
>
>pair(): first(int_set::iterator()), second(int_set::iterator()) {}
>
>and here we hit a problem, since p.first and p.last are
>copy-constructed from singular iterators, which is undefined!!
>
>So I've got three questions:
>
>1. Is my analysis correct in that the second program engenders
>undefined behavior?

Yes, I think so.

>2. If so, isn't this a little too restrictive? The second variant
>seems a straightforward reformulation of the first one, so I found
>the issue annoying. Would be there a problem in allowing an
>iterator to be copy-constructed from a singular iterator?

Yes, certainly in the case of pointers:
int* i;
int* p = i;//undefined behaviour, might be copying trap representation

However, perhaps this could be added: a value-initialized iterator can
be copied. This works for pointers, since a value initialized pointer
is a null pointer, and it could be made to work for other iterators
(by giving them suitable default constructors where necessary).

>3. Or, if we are to blame std::pair instead, why the default ctor is
>defined in this way? I don't see a problem in requiring that
>default construction behave like
>
>pair(): first(), second() {}
>
>rather than what the std says. Could this qualify as a DR?

I think that would be a harmless and worthwhile change in any case -
there's no good reason to copy in default values when
value-initialization does the same and potentially more efficiently.

Currently it requires excessively careful coding to avoid undefined
behaviour, and something should be done about it. Note that
vector<set<T>::iterator> also has a similar problem - resize cannot
safely be called without passing a valid iterator as the second
argument. Fixing it so that value initialized iterators can be copied
seems like the best fix to me; most platforms wouldn't require any
changes and only those that have trap representations of certain types
would need any modification.

Tom

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Fri, 23 Jul 2004 16:12:27 GMT
Raw View
Joaqu?n M? L?pez Mu?oz wrote:
>
> The default constructor of p behaves (according to std 20.2.2.2)
> like this:
>
> pair(): first(int_set::iterator()), second(int_set::iterator()) {}
>
> and here we hit a problem, since p.first and p.last are
> copy-constructed from singular iterators, which is undefined!!
>
> So I've got three questions:
>
> 1. Is my analysis correct in that the second program engenders
> undefined behavior?

AFAICT, yes.

> 2. If so, isn't this a little too restrictive? The second variant
> seems a straightforward reformulation of the first one, so I found
> the issue annoying. Would be there a problem in allowing an
> iterator to be copy-constructed from a singular iterator?

Don't know... I also can't see the reason why a singular iterator cannot
be copy-constructed, but the people who wrote the standard must have
seen it as it's explictly forbidden.

> 3. Or, if we are to blame std::pair instead, why the default ctor is
> defined in this way? I don't see a problem in requiring that
> default construction behave like
>
> pair(): first(), second() {}
>
> rather than what the std says. Could this qualify as a DR?

This qualify as a DR to me. There's no reason to require the copy even
if it is probably going to be optimized away, especially now that TC1
has introduced the notion of value-initialization.

Regards,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]