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 ]