copy_n should result in a one past the end input iterator

Robert Young yayooo@gmail.com
Mon Nov 21 03:17:00 GMT 2016


/*
gcc -Wall -Wextra -std=c++11 copy_n_vs_copy.cpp -lstdc++ -o copy_n_vs_copy

One Past the End
https://gcc.gnu.org/onlinedocs/libstdc++/manual/iterators.html#iterators.predefined.end

BUG location:
/usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h

*/

#include <assert.h>
#include <iostream>
#include <sstream>
#include <algorithm>

int main()
 {
  std::string i("abc");
  std::string o;
  std::istringstream t;

  t=std::istringstream(i);
  o.clear();
  assert(3==t.rdbuf()->in_avail());
  std::copy(std::istreambuf_iterator<char>(t.rdbuf()),
   std::istreambuf_iterator<char>(),back_inserter(o));
  std::cout<<"Test1(copy):\tResult_size:"<<o.size()<<"\tResult:\""<<o
   <<"\"\tin_avail:"<<t.rdbuf()->in_avail()<<std::endl;
  assert(0==t.rdbuf()->in_avail()); /* OK! */

  t=std::istringstream(i);
  o.clear();
  assert(3==t.rdbuf()->in_avail());
  std::copy_n(std::istreambuf_iterator<char>(t.rdbuf()),
   3,back_inserter(o));
  std::cout<<"Test2(copy_n):\tResult_size:"<<o.size()<<"\tResult:\""<<o
   <<"\"\tin_avail:"<<t.rdbuf()->in_avail()<<std::endl;
  assert(1==t.rdbuf()->in_avail()); /* WHY? */

  return(0);
 }

/*
Test1(copy):  Result_size:3   Result:"abc"    in_avail:0
Test2(copy_n):  Result_size:3   Result:"abc"    in_avail:1
*/
-------------- next part --------------
--- /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h	2015-02-19 20:57:40.000000000 +0000
+++ /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h	2015-02-19 20:57:40.000000000 +0000
@@ -762,9 +762,8 @@
 	    {
 	      *__result = *__first;
 	      ++__result;
-	      if (--__n > 0)
-		++__first;
-	      else
+	      ++__first;
+	      if (--__n <= 0)
 		break;
 	    }
 	}


More information about the Gcc-bugs mailing list