Bug 26020 - std::advance() isn't stable for floating point numbers
Summary: std::advance() isn't stable for floating point numbers
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.0.2
: P3 normal
Target Milestone: 4.2.0
Assignee: Paolo Carlini
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-29 23:06 UTC by André Wöbbeking
Modified: 2006-10-17 15:18 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-01-30 00:24:19


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description André Wöbbeking 2006-01-29 23:06:34 UTC
Hi,

i.e. code like

list<int> bla;
// insert some stuff into bla
list<int>::iterator it(bla.begin());
advance(it, bla.size() * 0.5);

can lead to an endless loop. I know that the code is "broken" but it should work nevertheless. Please change the code to < 0 and > 0, not just while (n--).


Cheers,
André
Comment 1 Andrew Pinski 2006-01-29 23:32:31 UTC
What does the standard says about this case?
Comment 2 André Wöbbeking 2006-01-29 23:40:38 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

On Monday 30 January 2006 00:32, pinskia at gcc dot gnu dot org wrote:
> ------- Comment #1 from pinskia at gcc dot gnu dot org  2006-01-29
> 23:32 ------- 
> What does the standard says about this case?

Don't know, but I was suprised that Distance is a template parameter.
Comment 3 Paolo Carlini 2006-01-30 00:24:19 UTC
AFAICS, the standard is silent about this issue. I think the suggested change is correct.
Comment 4 Gabriel Dos Reis 2006-01-30 00:35:26 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| AFAICS, the standard is silent about this issue. I think the suggested change
| is correct.

I believe Martin Sebor filled a related PR, whereby we should have
converted n to *some* integral type before proceeding...

-- Gaby
Comment 5 Paolo Carlini 2006-01-30 00:45:45 UTC
(In reply to comment #4)
> | AFAICS, the standard is silent about this issue. I think the suggested
> | change is correct.
> 
> I believe Martin Sebor filled a related PR, whereby we should have
> converted n to *some* integral type before proceeding...

I was also under that impression. That issue, however, was about Size in algos, which, at least, is required to be convertible to an integral type. I don't think we even have such *minimal* requirement here... What do you suggest? Should the LWG discuss such kind of requirements for Distance too? In the meanwhile suspend? I have no strong opinions...
Comment 6 Paolo Carlini 2006-01-30 00:57:45 UTC
Hi again. On second tought, I don't think we have an issue here. Maybe of QoI only, at most. The reason is that, according to 24.1/9, Distance is a difference type in the "following sections". A bit vague, but that seem to imply to also the template argument Distance in 24.3.4 is a difference type...
Comment 7 Gabriel Dos Reis 2006-01-30 01:05:23 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| ------- Comment #5 from pcarlini at suse dot de  2006-01-30 00:45 -------
| (In reply to comment #4)
| > | AFAICS, the standard is silent about this issue. I think the suggested
| > | change is correct.
| > 
| > I believe Martin Sebor filled a related PR, whereby we should have
| > converted n to *some* integral type before proceeding...
| 
| I was also under that impression. That issue, however, was about Size in algos,

sorry; memory failing.

| which, at least, is required to be convertible to an integral type. I don't
| think we even have such *minimal* requirement here... What do you suggest?

reading the standard specification let me under the impression that
Distance is supposed to "related" to difference_type.  For example
the distance between the p before and after calling distance(p, n) is
supposed to be n.  So I would suggest conversion to the
difference_type of the iterator as a momentary resolution.

| Should the LWG discuss such kind of requirements for Distance too?

Definitely.

| In the meanwhile suspend? I have no strong opinions...

I'm not sure the resolution would introduce an ABI breakage, so I
would say let's do both; but I'm open to other alternatives.

-- Gaby
Comment 8 Gabriel Dos Reis 2006-01-30 01:07:44 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Hi again. On second tought, I don't think we have an issue here. Maybe of QoI
| only, at most. The reason is that, according to 24.1/9, Distance is a
| difference type in the "following sections". A bit vague, but that seem to
| imply to also the template argument Distance in 24.3.4 is a difference type...

That matches my interpretation --- hence Distance must behave "like"
an integral type -- but still, the question is exactly what kind of
relation does it have with say
std::iterator<FowardIterator>::difference_type. 

-- Gaby
Comment 9 Paolo Carlini 2006-01-30 01:09:23 UTC
(In reply to comment #7)
> reading the standard specification let me under the impression that
> Distance is supposed to "related" to difference_type.  For example
> the distance between the p before and after calling distance(p, n) is
> supposed to be n.  So I would suggest conversion to the
> difference_type of the iterator as a momentary resolution.

Excellent idea.

> I'm not sure the resolution would introduce an ABI breakage, so I
> would say let's do both; but I'm open to other alternatives.

Agreed, let's implement your suggestion and send a note to the reflector (and Martin, already working on the Size issue). Thanks!
Comment 10 André Wöbbeking 2006-01-30 07:07:59 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

On Monday 30 January 2006 02:09, pcarlini at suse dot de wrote:
> ------- Comment #9 from pcarlini at suse dot de  2006-01-30 01:09
> ------- (In reply to comment #7)
>
> > reading the standard specification let me under the impression that
> > Distance is supposed to "related" to difference_type.  For example
> > the distance between the p before and after calling distance(p, n)
> > is supposed to be n.  So I would suggest conversion to the
> > difference_type of the iterator as a momentary resolution.
>
> Excellent idea.

FYI, I suggested tests for > 0 and < 0 as MSVC 7.1 does it that way. 

If you convert Distance to difference_type the question is what happens 
if Distance is i.e. 0.2. Do you advance by 0 or 1 position?
Comment 11 Gabriel Dos Reis 2006-01-30 07:54:05 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

"Woebbeking at web dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| On Monday 30 January 2006 02:09, pcarlini at suse dot de wrote:
| > ------- Comment #9 from pcarlini at suse dot de  2006-01-30 01:09
| > ------- (In reply to comment #7)
| >
| > > reading the standard specification let me under the impression that
| > > Distance is supposed to "related" to difference_type.  For example
| > > the distance between the p before and after calling distance(p, n)
| > > is supposed to be n.  So I would suggest conversion to the
| > > difference_type of the iterator as a momentary resolution.
| >
| > Excellent idea.
| 
| FYI, I suggested tests for > 0 and < 0 as MSVC 7.1 does it that way. 
| 
| If you convert Distance to difference_type the question is what happens 
| if Distance is i.e. 0.2. Do you advance by 0 or 1 position?

does not that follow from the conversion rule?

-- Gaby
Comment 12 André Wöbbeking 2006-01-30 12:03:54 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

On Monday 30 January 2006 08:54, gdr at integrable-solutions dot net 
wrote:
> ------- Comment #11 from gdr at integrable-solutions dot net 

> | FYI, I suggested tests for > 0 and < 0 as MSVC 7.1 does it that
> | way.
> |
> | If you convert Distance to difference_type the question is what
> | happens if Distance is i.e. 0.2. Do you advance by 0 or 1 position?
>
> does not that follow from the conversion rule?

Of course. I meant what should it do. Do you want it to advance by 0 or 
1 position? Do we just use a simple cast or do we need to do some 
rounding? AFAIK MSVC advance by 1 in this case.
Comment 13 Gabriel Dos Reis 2006-01-30 12:50:39 UTC
Subject: Re:  std::advance() isn't stable for floating point numbers

"Woebbeking at web dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Subject: Re:  std::advance() isn't stable for floating point numbers
| 
| On Monday 30 January 2006 08:54, gdr at integrable-solutions dot net 
| wrote:
| > ------- Comment #11 from gdr at integrable-solutions dot net 
| 
| > | FYI, I suggested tests for > 0 and < 0 as MSVC 7.1 does it that
| > | way.
| > |
| > | If you convert Distance to difference_type the question is what
| > | happens if Distance is i.e. 0.2. Do you advance by 0 or 1 position?
| >
| > does not that follow from the conversion rule?
| 
| Of course. I meant what should it do. Do you want it to advance by 0 or 
| 1 position? Do we just use a simple cast or do we need to do some 
| rounding? AFAIK MSVC advance by 1 in this case.

Given that Distance is supposed to behave "like" en integral type in
the first place, I would simply use:

  (1) implicit conversion to convert it to difference_type;
  (2) advance the number of time computed from (1).

-- Gaby
Comment 14 paolo@gcc.gnu.org 2006-10-17 15:17:47 UTC
Subject: Bug 26020

Author: paolo
Date: Tue Oct 17 15:17:32 2006
New Revision: 117827

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117827
Log:
2006-10-17  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/26020
	* include/bits/stl_iterator_base_funcs.h (advance): Convert
	distance parameter to iterator_traits<>::difference_type.
	* testsuite/24_iterators/26020.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/24_iterators/26020.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/stl_iterator_base_funcs.h

Comment 15 Paolo Carlini 2006-10-17 15:18:26 UTC
Fixed for 4.2.0.