Topic: Possible Defect report in various mutating algorithms
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Tue, 1 Mar 2005 18:20:01 GMT Raw View
In article <cvipf2$egq$1@pump1.york.ac.uk>,
caj@cs.york.ac.uk (Chris Jefferson) wrote:
> I'm fairly sure this is a fairly simple defect report to various
> mutating algorithms, but I thought I would post before reporting it in
> an "offical" defect report for comments.
>
> Various algorithms (including remove and list::remove if passed an
> element of the list, and possibly others) take a parameter by reference.
> They then operate (and possibly alter) some change) a range based on
> that parameter.
>
> Consider for example the following code:
>
> A[]={0,1,0,1};
> printf("%d,%d,%d",std::remove(A,A+4,*A)-A,A[0],A[1]);
>
> It might be expected this would return "2,1,1", meaning that it left two
> values, both of them one. On g++ 3.3 however, it returns "2,1,0",
> because the after the first delete operation the value at *A is changed.
>
> The only reasonable implementation (I believe) is to simply say that if
> any parameters passed to a mutating algorithm could be changed during
> its execution, then the behaviour is undefined.
>
> The main I ask this is that I would like to add a test to a debugging
> C++ standard library implementation which checks exactly this condition,
> but wanted to first of all check that it should infact be undefined
> behaviour :)
Imho your report and resolution are on target (modulo minor wording
issues).
-Howard
---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Thu, 3 Mar 2005 06:48:42 GMT Raw View
"Chris Jefferson" <caj@cs.york.ac.uk> wrote in message
news:cvipf2$egq$1@pump1.york.ac.uk...
| I'm fairly sure this is a fairly simple defect report to various
| mutating algorithms, but I thought I would post before reporting it in
| an "offical" defect report for comments.
|
| Various algorithms (including remove and list::remove if passed an
| element of the list, and possibly others) take a parameter by reference.
| They then operate (and possibly alter) some change) a range based on
| that parameter.
|
| Consider for example the following code:
|
| A[]={0,1,0,1};
| printf("%d,%d,%d",std::remove(A,A+4,*A)-A,A[0],A[1]);
|
| It might be expected this would return "2,1,1", meaning that it left two
| values, both of them one. On g++ 3.3 however, it returns "2,1,0",
| because the after the first delete operation the value at *A is changed.
hm... AFAICT, the above code gives implementation defined behavior
because you are not guaranteed that evaluation occurs from left to right
in a function call.
-Thorsten
---
[ 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: caj@cs.york.ac.uk (Chris Jefferson)
Date: Sat, 5 Mar 2005 00:12:05 GMT Raw View
Thorsten Ottosen wrote:
> "Chris Jefferson" <caj@cs.york.ac.uk> wrote in message
> news:cvipf2$egq$1@pump1.york.ac.uk...
> | I'm fairly sure this is a fairly simple defect report to various
> | mutating algorithms, but I thought I would post before reporting it in
> | an "offical" defect report for comments.
> |
> | Various algorithms (including remove and list::remove if passed an
> | element of the list, and possibly others) take a parameter by reference.
> | They then operate (and possibly alter) some change) a range based on
> | that parameter.
> |
> | Consider for example the following code:
> |
> | A[]={0,1,0,1};
> | printf("%d,%d,%d",std::remove(A,A+4,*A)-A,A[0],A[1]);
> |
> | It might be expected this would return "2,1,1", meaning that it left two
> | values, both of them one. On g++ 3.3 however, it returns "2,1,0",
> | because the after the first delete operation the value at *A is changed.
>
> hm... AFAICT, the above code gives implementation defined behavior
> because you are not guaranteed that evaluation occurs from left to right
> in a function call.
>
Woops! Thats true.. sorry about that!
However, the same problem still occurs from:
A[]={0,1,0,1};
std::remove(A,A+4,*A);
printf("%d,%d",A[0],A[1]);
Chris
---
[ 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: petebecker@acm.org (Pete Becker)
Date: Sat, 5 Mar 2005 00:12:12 GMT Raw View
Thorsten Ottosen wrote:
>
> hm... AFAICT, the above code gives implementation defined behavior
> because you are not guaranteed that evaluation occurs from left to right
> in a function call.
>
Sorry to sound picky, but it's not implementation defined, it's
unspecified. The difference being that the former requires the
implementation to document its behavior; the latter does not. In both
cases, though, the code is valid.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ 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: caj@cs.york.ac.uk (Chris Jefferson)
Date: Sat, 26 Feb 2005 15:41:46 GMT Raw View
I'm fairly sure this is a fairly simple defect report to various
mutating algorithms, but I thought I would post before reporting it in
an "offical" defect report for comments.
Various algorithms (including remove and list::remove if passed an
element of the list, and possibly others) take a parameter by reference.
They then operate (and possibly alter) some change) a range based on
that parameter.
Consider for example the following code:
A[]={0,1,0,1};
printf("%d,%d,%d",std::remove(A,A+4,*A)-A,A[0],A[1]);
It might be expected this would return "2,1,1", meaning that it left two
values, both of them one. On g++ 3.3 however, it returns "2,1,0",
because the after the first delete operation the value at *A is changed.
The only reasonable implementation (I believe) is to simply say that if
any parameters passed to a mutating algorithm could be changed during
its execution, then the behaviour is undefined.
The main I ask this is that I would like to add a test to a debugging
C++ standard library implementation which checks exactly this condition,
but wanted to first of all check that it should infact be undefined
behaviour :)
Chris
---
[ 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 ]