This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
patch -- more fstream.tcc funkiness
- To: libstdc++@sourceware.cygnus.com
- Subject: patch -- more fstream.tcc funkiness
- From: Phil Edwards <pedwards@jaj.com>
- Date: Tue, 8 Jun 1999 19:05:44 -0400
It would save time now if we all went insane, don't you think?
Here's the testcase that I keep using:
#include <fstream>
int main ()
{
std::ifstream IN ("input_file");
std::ofstream OUT ("output_file");
//OUT << "this is a test\n";
OUT << IN.rdbuf();// << std::flush;
}
After the patch I sent last Thursday, this testcase worked. I now have
current CVS soruces plus my patch...
Today, how's this for fun: only the first 4 characters of input_file
are copied. The remaining N-4 characters are in fact allocated and
written to output_file, but they are NUL's rather than the correct data.
The patch is here. Explanation follows. Appended is the testsuite
results (filebuf tests remain pass/pass/fail after this patch).
1999-06-08 Phil Edwards <pedwards@ball.com>
* bits/fstream.tcc (basic_filebuf::underflow): Fix, rename local vars.
Index: bits/fstream.tcc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/bits/fstream.tcc,v
retrieving revision 1.21
diff -c -3 -r1.21 fstream.tcc
*** fstream.tcc 1999/06/03 00:47:35 1.21
--- fstream.tcc 1999/06/08 22:38:02
***************
*** 209,227 ****
char* __conv_cur = __conv_buf;
_M_state_beg = _M_state_cur;
! __res_type __r = _M_fcvt->in(_M_state_cur,
__conv_buf,
__conv_buf + __r,
const_cast<const char*&>(__conv_cur),
_M_in_beg, _M_in_end, _M_in_cur);
! if (__r == codecvt_base::partial)
{
// XXX Retry with larger _M_buf size.
}
// Set pointers to internal and external buffers correctly. . .
! if (__r != codecvt_base::error)
{
if (_M_mode & ios_base::out)
_M_out_cur = _M_in_cur;
--- 209,227 ----
char* __conv_cur = __conv_buf;
_M_state_beg = _M_state_cur;
! __res_type __R = _M_fcvt->in(_M_state_cur,
__conv_buf,
__conv_buf + __r,
const_cast<const char*&>(__conv_cur),
_M_in_beg, _M_in_end, _M_in_cur);
! if (__R == codecvt_base::partial)
{
// XXX Retry with larger _M_buf size.
}
// Set pointers to internal and external buffers correctly. . .
! if (__R != codecvt_base::error)
{
if (_M_mode & ios_base::out)
_M_out_cur = _M_in_cur;
===================================================================
At the call to _M_fcvt->in, the __r being passed is the size of the
buffer. The results of the call are assigned to a new __r of completely
different type (a return status enum). The new __r /should/ be safe,
since it's a more local scope and /should/ hide the __r declared a few
lines earlier.
It doesn't. Why it didn't before is beyond me; this code doesn't seem
to have been touched in a while according to cvsweb. The __r being
passed in is /always/ given the value 4, rather than the variable size,
which means that only 4 bytes of valid data are copied into an array
that is correctly-sized everywhere else.
The patch simply changes the new __r to __R, and the testcase above
works again. While the shadowing of names whould work, it looks to
be more "cute" than what the compiler could handle, and difficult
as hell to read in later scopes in the same function.
Phil
(If you reply to the list, please don't cc another copy to me. Thanks!)
host: Linux 2.2.5 #1 Wed Apr 7 10:42:48 EDT 1999 i586
compiler: egcs-2.93.21
compiler flags: -g -O2 -DDEBUG_ASSERT
time exec text data total name
4 pass 70740 15573 420295 header_ciso646.st-exe
3 fail 0 0 0 headers.st-exe
16 pass 98762 16364 757653 capacity.st-exe
4 pass 91914 16236 615129 char_traits.st-exe
7 pass 94890 16396 651352 compare.st-exe
9 pass 94858 16460 669427 ctor_copy_dtor.st-exe
4 fail 0 0 0 element_access.st-exe
12 pass 97178 16972 692794 insert.st-exe
8 pass 96538 16300 642369 nonmember.st-exe
7 pass 92698 16257 643058 operations.st-exe
6 pass 89802 16012 590563 vector_capacity.st-exe
29 pass 101562 16268 791488 iterator.st-exe
1 pass 70884 15473 428854 modf_float.st-exe
6 pass 86842 15933 561408 valarray.st-exe
31 pass 368966 32428 2599145 boolfmt.st-exe
26 fail 370866 32268 2535315 filebuf.st-exe
19 pass 357190 32268 2487856 ios_members_static.st-exe
1 fail 0 0 0 iostream_objects.st-exe
30 pass 367110 32652 2579170 istringstream_formatted.st-exe
26 pass 365430 32460 2568388 octfmt.st-exe
65 pass 376594 32460 2669004 stringbuf.st-exe
36 pass 366774 32588 2574982 stringstream.st-exe